Subj : Re: signaling threads from a forked child? To : comp.programming.threads From : markh@compro.net Date : Tue Aug 09 2005 05:24 am Well, I've got everything working. However I don't understand why I don't seem to need to use the pthread_mutexattr_setpshared/pthread_condattr_setpshared calls at all. It appears that just insuring the mutexes/convars are in fact in a SHM is all that I needed for this to work. Below is a functional test case that works with or without the above mentioned funtions. Why does it work without them. What are they really doing or what are they really indended to be doing for me. I hope it's ok to post code here. include #include #include #include #include #include #include #include #include #include typedef struct EMU_DSI { pthread_mutex_t lock; pthread_cond_t nonzero; unsigned count; } EMU_DSI; EMU_DSI *Q; char *attachp(key_t key, size_t size, void *address, int *id); static int shmflag = SHM_R | SHM_W | IPC_CREAT | 00666; void *thread_code( void *args ); int true = 1; int child; int MAXCOUNT = 10; int DoChild = 1; int DoParent = 0; char * char_ADDR; int shm_id; key_t key; int main() { pthread_mutexattr_t psharedm; pthread_condattr_t psharedc; pthread_t thread_id; char_ADDR = attachp(0, (sizeof (EMU_DSI)), 0, &shm_id); Q = (EMU_DSI *)char_ADDR; /* pthread_mutexattr_init(&psharedm); pthread_mutexattr_setpshared(&psharedm, PTHREAD_PROCESS_SHARED); pthread_condattr_init(&psharedc); pthread_condattr_setpshared(&psharedc, PTHREAD_PROCESS_SHARED); */ pthread_mutex_init(&Q->lock, &psharedm); pthread_cond_init(&Q->nonzero, &psharedc); Q->count = 0; printf("Parent: Starting thread\n"); pthread_create(&thread_id, NULL, thread_code, NULL ); sleep(2); child = fork(); if (child == 0) { printf("I am the child. My pid = %d\n",getpid()); while (Q->count < MAXCOUNT) { if (DoChild) { printf("Child: Signaling thread\n"); pthread_mutex_lock(&Q->lock); pthread_cond_signal(&Q->nonzero); Q->count++; pthread_mutex_unlock(&Q->lock); printf("Child: Signaled thread\n"); sleep(1); } else { sched_yield(); } } printf("child exiting: count = %d\n",Q->count); } else { printf("I am the parent. My pid = %d\n",getpid()); while (Q->count < MAXCOUNT) { if (DoParent) { printf("Parent: Signaling thread\n"); pthread_mutex_lock(&Q->lock); pthread_cond_signal(&Q->nonzero); Q->count++; pthread_mutex_unlock(&Q->lock); printf("Parent: Signaled thread\n"); sleep(1); } else { sched_yield(); } } sleep(1); printf("parent exiting: count = %d\n",Q->count); } exit(0); } void *thread_code( void *args ) { printf("thread_code started. count = 0x%08x\n",Q->count); while (Q->count < MAXCOUNT) { printf("thread_code: sleeping\n"); pthread_mutex_lock(&Q->lock); pthread_cond_wait(&Q->nonzero, &Q->lock); pthread_mutex_unlock(&Q->lock); printf("thread_code: wokeup\n"); } printf("thread_code exiting: count = %d\n",Q->count); return (0); } char *attachp(key_t key, size_t size, void *address, int *id) { char *pstart; /* Start address of shm */ int shmid; shmflag = SHM_R | SHM_W | IPC_CREAT | 00666; shmid = shmget(key,size,shmflag); if (shmid <0) { perror("shmget failed:"); exit(1); } pstart = (char *)shmat(shmid,address,SHM_RND); if ( (int long) pstart == -1 ) { perror("shmat failed:"); exit(1); } *id = shmid; return(pstart); } .