I am writing a program using shared memory and semaphores for ipc. There is one main server process that creates shared memory and semaphores. Any number of client processes can join the shared memory and read and write to it, when allowed. Semaphores provide a blocking mechanism for controlling reading and writing. Everything works fine except when I try to close the client. The semaphore block for accessing shared memory is in the stream and when the process ends, I have no way to free the semaphore block so that the stream exits it correctly. How can i do this? This is for Linux.
To be specific, there is one shm and two sems. First records of sample blocks and reading of second blocks. When the client has something to write, it expects write sem to be 0, then sets it to 1, writes, and then sets the read sem to 0, which frees the waiting server to read what the client wrote. after reading the server sets the sem record back to 0 and the next client in the line gets the record. It hangs on a semop call that issues when read sem is 0. This semop call is in a thread, and I need to figure out how to exit this thread correctly before allowing the main thread.
Here is an example of what I want to do, but it doesn’t work (sleep pretends to be an ubiquitous semop call):
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void termination_handler (int signum) {
printf( "Got Signal\n" );
}
void *threadfunc( void *parm ) {
struct sigaction action;
action.sa_handler = termination_handler;
sigemptyset( &action.sa_mask );
action.sa_flags = 0;
sigaction( SIGUSR1, &action, NULL );
printf("Thread executing\n");
sleep( 100 );
pthread_exit( NULL );
}
int main() {
int status;
pthread_t threadid;
int thread_stat;
status = pthread_create( &threadid, NULL, threadfunc, NULL );
if ( status < 0) {
perror("pthread_create failed");
exit(1);
}
sleep( 5 );
status = pthread_kill( threadid, SIGUSR1 );
if ( status < 0 )
perror("pthread_kill failed");
status = pthread_join( threadid, (void *)&thread_stat );
if ( status < 0 )
perror("pthread_join failed");
exit( 0 );
}