JSON
JSON

Reputation: 1835

catching socket and signal events with pselect

I'm making a messaging service that needs to use both socket io and shared memory. The routine will be the same regardless of where the input comes from, with the only difference being local messages will be passed via shared memory and non-local messages over a socket. Both events will have to unblock the same pselect call. At this point I think the best option might be to send a signal whenever a message is written to shared memory and use it to interrupt a pselect call but I'm not quite sure how this would be done or even if it's the best route.

I'm not used to using signals. what's the best way to accomplish this?

Upvotes: 0

Views: 903

Answers (5)

JSON
JSON

Reputation: 1835

I did some additional looking and came across signalfd(2). I believe this will be the best solution - very similar to Basile Starynkevitch's suggestion but without the overhead of standard pipes and done within the kernel rather than userspace.

Upvotes: 0

Useless
Useless

Reputation: 67762

If you want to use signals, use sigqueue to send them - you can send an integer payload with this, for example an offset into your shared memory.

Make sure to register your signal handler with sigaction and use the sa_sigaction callback: the siginfo_t->si_int member will contain that payload.

In general, I'm not sure I can recommend using this mechanism instead of a unix pipe or eventfd, because I'm not sure whether signal delivery is really tuned for speed as you hope: benchmark to be sure.


PS. performance aside, one reason signals feel a bit icky is that you lose the opportunity to have a "well-known" rendezvous like an inet or unix port, and instead have to go looking for a PID. Also, you have to be very careful about masking to make sure the signal is delivered where you want.

PPS. You raise or send a signal - you don't throw it. That's for exceptions.

Upvotes: 1

I would consider using a pipe (see pipe(2)) or an AF_UNIX local unix(7) socket(2) (as commented by caf) at least to transmit control information -for synchronization- about the shared memory (i.e. tell when it has changed, that is when a message has been sent thru shared memory, etc.). Then you can still multiplex with e.g. poll(2) (or ppoll(2) or pselect(2) etc...)

I don't think that synchronization using signals is the right approach: signals are difficult to get right (so coding is tricky) and they are not more efficient than exchanging a few bytes on some pipe.

Did you consider to use MPI?

Upvotes: 5

liangdong from baidu
liangdong from baidu

Reputation: 351

pipe+select+queue+lock, nothing else.

Upvotes: -2

dunc123
dunc123

Reputation: 2723

If you only want to signal between processes rather than pass data, then an eventfd (see eventfd(2)) will allow you to use select() with less overhead than a pipe. As with a pipe solution, the processes will require a parent/child relationship.

Upvotes: 3

Related Questions