How to implement synchronous rpc between processes on the samemachine
Hi
I hope i have not posted at the wrong place. Kindly read the full post
before lamenting as off topic:
Basically i need functionality similar to that provided by Solaris
DOORS( it is a properietry and quite efficient IPC by SUN)
To explain it:
I have process p1 and process p2 on the same computer and i can call a
function foo( ) in process p2 from p1 i.e rpc( on the same host) using
the function door_call( which takes arguments and writes and
This function door_call is synchronous. Moreover the DOOR library
makes sure that the function f( ) is executed in a concurrent manner
i.e it internally maintains a pool of threads i.e the server( process
p2 is a concurrent server )
So thats all about my requirement. I cannot use DOORS because i am now
porting the project to Linux.
So here is my design the i want you to kindly kindly review and give
me lots of details, caveats, shortcomings, suggestions etc as i am not
very well good in multithreaded programming and would like to have
your guidance rather that implement something that takes a lot of
locks and generates a lot of threads but is essentially serialized
code and add to it the problem of deadlocks and races. I need
efficiency and scalability in design and so require you geeks out
there to just review this design and provide your much needed inputs.
Here is my Design for a function my_door with functionlity similar to
door_call in Solaris DOORS:
I am planning to use shared memory to achieve the above functionality.
All the mutexes and condition variables i will refer below are created
in shared memory i.e mutexes M1 and M2 and condition variables C1 and
C2( with their attributes being PTHREAD_PROCESS_SHARED ). Shared
memory also contains a boolean flag fay FLAG initially set to false
and a data say int X
The server thread takes a lock M1and then waits for condition
variable C1 waiting for FLAG to be true( thereby also releasing lock
M1 ). The client i.e p1 invokes the function, changes the variable
FLAG to true and then issues pthread_cond_signal( &C1 ), and starts
to wait on condition variable C2( thereby also releasing lock M1) i.e
allow the server routine to execute and allow the server routine to
write to variable X.
The server thread gets the signal, locks mutex M1 executes the called
function in its address space, writes the results to variable X signal
pthread_cond_signal(you do remember that client thread is waiting for
results ? ) and then unlocks mutex M1. The client thread now wakes up
locks mutex M1, reads the result written to variable x and then the
function my_door returns.
I guess the above design sucks. The project involves many threads
calling door_call and the server should be concurrent but here i guess
i am just serializing it all just to make it synchronous.( what if say
10 threads from client side call my_door, then my server would be
infact just serializing
Moreover the above is such a trivial case, i want client process to
write arguments, then signal the server to read the arguments. the
server reads the arguments executes the function and write the results
and signals the client to read the results ?
Is it possible to do. I badly need your suggestions.
Kindly help this poor soul tormented by such a herculean task :)
Thats all my little brain could produce after thinking for about an
hour.
Please guide me as how should i get the above functionality with
scalability and *real* parallelism.
If i was unable to explain my design then please suggest something you
would like to implement to solve the above problem i.e have some
synchronous rpc between processes on same machine so that i can pass
arguments and receive results.
Thanks for your patience. Waiting eagerly for your comments
Regards
Kartik Mahajan
Re: How to implement synchronous rpc between processes on the same machine
"lali.cpp" <lali.cpp@gmail.com> writes:[color=blue]
> Basically i need functionality similar to that provided by Solaris
> DOORS( it is a properietry and quite efficient IPC by SUN)
> To explain it:
>
> I have process p1 and process p2 on the same computer and i can call a
> function foo( ) in process p2 from p1 i.e rpc( on the same host) using
> the function door_call( which takes arguments and writes and
>
> This function door_call is synchronous. Moreover the DOOR library
> makes sure that the function f( ) is executed in a concurrent manner
> i.e it internally maintains a pool of threads i.e the server( process
> p2 is a concurrent server )[/color]
[...]
[color=blue]
> Here is my Design for a function my_door with functionlity similar to
> door_call in Solaris DOORS:
> I am planning to use shared memory to achieve the above functionality.
> All the mutexes and condition variables i will refer below are created
> in shared memory i.e mutexes M1 and M2 and condition variables C1 and
> C2( with their attributes being PTHREAD_PROCESS_SHARED ). Shared
> memory also contains a boolean flag fay FLAG initially set to false
> and a data say int X
>
> The server thread takes a lock M1and then waits for condition
> variable C1 waiting for FLAG to be true( thereby also releasing lock
> M1 ). The client i.e p1 invokes the function, changes the variable
> FLAG to true and then issues pthread_cond_signal( &C1 ), and starts
> to wait on condition variable C2( thereby also releasing lock M1) i.e
> allow the server routine to execute and allow the server routine to
> write to variable X.
>
> The server thread gets the signal, locks mutex M1 executes the called
> function in its address space, writes the results to variable X signal
> pthread_cond_signal(you do remember that client thread is waiting for
> results ? ) and then unlocks mutex M1. The client thread now wakes up
> locks mutex M1, reads the result written to variable x and then the
> function my_door returns.[/color]
Another idea would be to use PF_UNIX datagram sockets. The server
would create such a socket, bind it to a 'well-known' address and
create some number of threads blocking in a recvfrom-call on this socket.
Client processes would create such a socket and bind it to a
per-process-and-thread name. Linux supports an abstract namespace for
such sockets which could be handy here. When a client wants to invoke
a 'remote procedure', it would need to create a message containing
some 'procedure identifier' and a parameter block and send this
message to the server address afterwards. Then, it would block on the
client socket to use until receiving a reply (or a timeout,
presumably). One of the server threads would receive the message, call
the requested function with the passed parameters, create a message
containing the procedure identifier and 'the result' in some (to be
defined) data format and send that to the client address received as
part of the recvfrom. As soon as the client has received this message,
the 'synchronous "remote" procedure call' has completed and the
results can be used.
No further synchronization between clients and servers would be
necessary and this would 'naturally' support any number of client
threads from any number of processes calling any number of 'remote
procedures' using any number of concurrent 'server threads' for
execution (within some 'reasonable limits' for 'any number',
obviously).