Click to See Complete Forum and Search --> : sending signals (C/C++)


tecknophreak
03-09-2004, 12:42 PM
I've got a struct which is basically a cicle buffer. I use this to transfer large amounts of data from one process to another. I'd like to make it like pipe or socket, as in I can do a read where it doesn't return until it has done a complete read(without going into a busy loop). I'd also like to set a signal(SIGIO) when the fifo has been written to.

I've got two threads sharing a fifo struct(global) and I can't think of how to get the SIGIO to the process which is waiting for the signal without hard-coding it in there.

I suppose it'll come down to writing a "simple" device driver huh? :rolleyes:

jim mcnamara
03-09-2004, 03:22 PM
Two comments:

You can't get a signal sent only to a specific thread. Either thread can receive the signal. This makes signal processing really tough.

Try using a semaphore - they are specifically meant to signal between cooperating threads.

tecknophreak
03-09-2004, 05:32 PM
Originally posted by jim mcnamara
You can't get a signal sent only to a specific thread.

One comment:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>


char sig1Recvd = 0;
char mainsig1Recvd = 0, mainsig2Recvd = 0;
int waitingPid = 0, mainPid = 0;

void sig1(int sig) {
sig1Recvd = 1;
}

void mainsig1(int sig) {
mainsig1Recvd = 1;
}

void mainsig2(int sig) {
mainsig2Recvd = 1;
}

void *waiting(void *arg) {
waitingPid = getpid();
signal(SIGUSR1, sig1);
while (sig1Recvd == 0);
printf("Waiting thread recvd a SIGUSR1!!\n");
sleep(1);
kill(mainPid, SIGUSR2);
pthread_exit(NULL);
}

int main() {
int res;
unsigned char array[10];
pthread_t waitThread;
void *threadResult;
mainPid = getpid();
signal(SIGUSR1, mainsig1);
signal(SIGUSR2, mainsig2);

res = pthread_create(&waitThread, NULL, waiting, NULL);

while (waitingPid == 0);
kill(waitingPid, SIGUSR1);


if (mainsig1Recvd != 0) {
printf("Main recvd a SIGUSR1??\n");
}
while (mainsig2Recvd == 0);
printf("Main recvd a SIGUSR2!!\n");

res = pthread_join(waitThread, &threadResult);
}

jim mcnamara
03-09-2004, 06:41 PM
From the man page on signal:


Threads Considerations
The signal disposition (such as catch/ignore/default) established by
signal() is shared by all threads in the process. Blocked signal
masks are maintained by each thread.


consider using sighold() if you feel signals are okay - I do not.

from pthreads:

POSIX 1.b SEMAPHORES
The semaphore functions specified in the POSIX 1.b standard can also
be used for synchronization in a multithreaded application. They
are the preferred method.

sem_init(),
sem_destroy()

Initialize/destroy contents of a semaphore.

sem_post(),
sem_wait(),
sem_trywait()

Increment/decrement semaphore value (possibly blocking).

bwkaz
03-09-2004, 09:05 PM
Originally posted by jim mcnamara
You can't get a signal sent only to a specific thread. Either thread can receive the signal. This makes signal processing really tough. True, but you can set a signal mask per thread. If you mask off the signal in one of the threads, only the other one will run your signal handler.

However, I really don't think a pipe or socket is a good way to do this. Shared memory and a semaphore to signal when it's ready are better (basically, Google for "producer consumer" or "bounded buffer", as those are the names generally given to this kind of problem -- reading any result from a .edu domain will probably explain enough of it). This problem's been solved before, often enough that they taught it to us as one of "those things you absolutely must know" in my threading class.

Try using a semaphore - they are specifically meant to signal between cooperating threads. I'd agree that this is most likely better. Finding an already-done implementation (or at least a good description of a working algorithm) won't hurt either, unless this is for an assignment. In which case, don't post it here -- your professor / teacher / whoever could easily be reading these forums also.