Thread: using pthread_cond across two processes via shared memory

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    269

    using pthread_cond across two processes via shared memory

    Hi,

    For some reason, I can't get a thread that waits on a condition to start when I call notify from another thread. They are separate processes, actually, and I create a shared memory segment between them.

    Here's the process that waits.

    Code:
    #include <stdlib.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include<pthread.h>
    #include <errno.h>
    #include<stdio.h>
    
    #define NUMSEG 5
    #define PROJID 1235
    
    struct _SYNC
    {
      int busy[NUMSEG];
      int dataready[NUMSEG];
      int dataend[NUMSEG];
      //pthread_mutex_t lock[NUMSEG];
      //pthread_cond_t dready[NUMSEG];	
      pthread_mutex_t * lock;
      pthread_cond_t *dready;
    }*syncvar;
    
    typedef struct _SYNC SYNC;
    
    int main(int argv, char *argc[])
    {
        key_t key;
        int shmid;
        
        if ((key = ftok("proxy", PROJID)) == -1) {
            perror("ftok");
            exit(1);
        }	
        
       
        if ((shmid = shmget(key, sizeof(SYNC), IPC_CREAT | 0666)) == -1) {
            perror("shmget");
            exit(1);
        }
    
        syncvar = (SYNC *) shmat(shmid, (void *)0, 0);
        if (syncvar == (SYNC *)(-1)) {
            perror("shmat");
            exit(1);
        }
    
        syncvar->lock = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)*NUMSEG);
        syncvar->dready = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)*NUMSEG);
        
        pthread_condattr_t cond_attr;
        pthread_condattr_init(&cond_attr);
        pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); 
        pthread_mutexattr_t m_attr;
        pthread_mutexattr_init(&m_attr);
        pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED); 
        int i;
        for(i=0;i<NUMSEG;i++)
          {
    	//pthread_mutex_destroy(&(syncvar->lock[i]));
            //pthread_cond_destroy(&(syncvar->dready[i]));	
    	pthread_mutex_init(&(syncvar->lock[i]),&m_attr);
    	pthread_cond_init(&(syncvar->dready[i]),&cond_attr);
          }
        
        pthread_mutex_lock(&(syncvar->lock[0]));
        syncvar->busy[0] = 5;
        //syncvar->busy[1] = 6;
        //syncvar->dready[0]=5;
        printf("%d\n",syncvar->busy[2]);
        pthread_cond_wait(&(syncvar->dready[0]),&(syncvar->lock[0]));
        printf("%d\n",syncvar->busy[1]);
        pthread_mutex_unlock(&(syncvar->lock[0]));
    
      /*   if (shmdt(syncvar) == -1) {
            perror("shmdt");
            exit(1);
        }*/
    
        printf("I have successfully got out of wait loop\n");	
    
      shmdt(syncvar);
      shmctl(shmid, IPC_RMID, NULL); 
          		
     /*   pthread_t threads[NUMTHREADS];
        int rc;
        for(int threadid=0;threadid<NUMTHREADS;threadid++)
        {
    	rc=pthread_create(&threads[threadid],NULL,syncplay,(void *)threadid);
    	if (rc) {
            printf("ERROR; return code from pthread_create() is %d\n", rc);
            exit(-1);
            }
        }
    
        for(int i=0;i<NUMTHREADS;i++)
        {
    	rc=pthread_join(threads[i],NULL);
    	if (rc) {
            printf("ERROR; return code from pthread_join() is %d\n", rc);
            exit(-1);
            }
        }	      
    */
    }
    Here is the process that signals

    Code:
    #include <stdlib.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include<pthread.h>
    #include <errno.h>
    #include<stdio.h>
    
    #define NUMSEG 5
    #define PROJID 1235
    
    struct _SYNC
    {
        int busy[NUMSEG];
        int dataready[NUMSEG];
        int dataend[NUMSEG];
        //pthread_mutex_t lock[NUMSEG];
        //pthread_cond_t dready[NUMSEG];	
        pthread_mutex_t * lock;
        pthread_cond_t * dready;
    }*syncvar;
    
    typedef struct _SYNC SYNC;
    
    int main(int argv, char *argc[])
    {
        key_t key;
        int shmid;
        
        if ((key = ftok("proxy", PROJID)) == -1) {
            perror("ftok");
            exit(1);
        }	
    
        if ((shmid = shmget(key, sizeof(SYNC),  0666)) == -1) {
            perror("shmget");
            exit(1);
        }
       
        syncvar = (SYNC *) shmat(shmid, (void *)0, 0);
        if (syncvar == (SYNC *)(-1)) {
            perror("shmat");
            exit(1);
        }
        //syncvar->lock = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)*NUMSEG);
        //syncvar->dready = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)*NUMSEG);
    
        pthread_condattr_t cond_attr;
        pthread_condattr_init(&cond_attr);
        pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); 
        pthread_mutexattr_t m_attr;
        pthread_mutexattr_init(&m_attr);
        pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED);   
    
        int i;
        for(i=0;i<NUMSEG;i++)
        {
    	pthread_mutex_init(&(syncvar->lock[i]),&m_attr);
    	pthread_cond_init(&(syncvar->dready[i]),&cond_attr);
        }
        
        pthread_mutex_lock(&(syncvar->lock[0]));
        printf("%d\n",syncvar->busy[0]);
        // printf("%d\n",syncvar->busy[1]);
        //syncvar->busy[2]=7;
        while(syncvar->busy[0] != 5)
        { 
    	printf("ready to signal\n");
          	pthread_cond_signal(&(syncvar->dready[0]));
    	syncvar->busy[1]=8;
            printf("signalled\n");
        }
        pthread_mutex_unlock(&(syncvar->lock[0]));
        
        printf("I have successfully signalled\n");	
    
        /*    if (shmdt(syncvar) == -1) {
    	  perror("shmdt");
    	  exit(1);
    	  }*/
        shmdt(syncvar);
        shmctl(shmid, IPC_RMID, NULL); 
    
        		
        /*   pthread_t threads[NUMTHREADS];
    	 int rc;
    	 for(int threadid=0;threadid<NUMTHREADS;threadid++)
    	 {
    	 rc=pthread_create(&threads[threadid],NULL,syncplay,(void *)threadid);
    	 if (rc) {
    	 printf("ERROR; return code from pthread_create() is %d\n", rc);
    	 exit(-1);
    	 }
    	 }
    
    	 for(int i=0;i<NUMTHREADS;i++)
    	 {
    	 rc=pthread_join(threads[i],NULL);
    	 if (rc) {
    	 printf("ERROR; return code from pthread_join() is %d\n", rc);
    	 exit(-1);
    	 }
    	 }	      
        */
    }
    I know the shared memory works because "5" is written by one process and read by another.

    I am at a loss.

    Here is how I compile

    Code:
    gcc -o shmem1 shmsample1.c -lpthread
    gcc -o shmem shmsample.c -lpthread
    run shmem first in one terminal, then in another, shmem1

    also create a file "proxy"... it can just be anything in there..

    Both codes init the condition and the attrs... even only making the "waiting" process init, it's still deadlocked....

    Any ideas?
    Last edited by dayalsoap; 11-09-2012 at 01:16 PM.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> //pthread_mutex_t lock[NUMSEG];
    >> //pthread_cond_t dready[NUMSEG];

    That is what you need to be doing. You're trying to share malloc'd memory as it is.

    gg

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    269
    Found the problem! Was initializing the conds in both files.

    also, not using malloc, just static arrays.

    Duh.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 3 types of processes accessing shared memory
    By Joanna91 in forum Linux Programming
    Replies: 8
    Last Post: 12-19-2011, 08:22 AM
  2. ICP using shared memory - how to sync child processes?
    By synthetix in forum C Programming
    Replies: 15
    Last Post: 06-15-2011, 12:59 PM
  3. accessing shared memory via forked processes
    By rklockow in forum C Programming
    Replies: 7
    Last Post: 06-30-2010, 05:44 PM
  4. Replies: 7
    Last Post: 02-06-2009, 12:27 PM
  5. shared libraries, datasegment and multiple processes
    By ashim_k1 in forum Linux Programming
    Replies: 1
    Last Post: 02-28-2008, 02:23 PM