deadlock

Mikko Työläjärvi mbsd at pacbell.net
Fri Nov 26 14:42:41 PST 2004


Hi Alexander,

On Fri, 26 Nov 2004, Alexander Bubnov wrote:

> /*
> Hello!
> Could you tell me why this exemple is deadlocked under FreeBSD, not Linux?
> (FreeBSD 4.10 and 5.2 , I have not tried under other versions)
>
> a string that includes this problem marked, see below the main function
>
> */
> #include<sys/types.h>
> #include<sys/ipc.h>
> #include<sys/sem.h>
> #include<errno.h>
> #include<pthread.h>
> #include<stdlib.h>
> #include<stdio.h>
>
> int Exit=0;/* uses in hand(), changes in main() */
> int ReStart,Start;/* semaphores ID which returns semget() */
> /*
>   Start semphore controls starting threads,
>   EXETHREADS - how many threads can start in one time
>      ReStart semaphore for wait when the starting threads display a string
> */
> struct sembuf dec={0},inc={0},op={0};/* they initilize in the main function*/
> void*hand(void*p){
>   do{
>       semop(Start,&dec,1);
>       if(Exit)break;
>       puts(p);
>       semop(ReStart,&inc,1);
>   }while(1);
>   fprintf(stderr,"bye, %s!\n",p);
>   return NULL;
> }
>
> #define MAXTHREADS 5
> #define EXETHREADS 2 /* number of threads which is executed in one time*/
> #define ITERAT 2 /* number of iterations, see the main function */
>
> int main(void){
>   char*s[MAXTHREADS]={"Mike","Leo","Don","Raph","Splinter"};
>   int i;
>   pthread_t thread[MAXTHREADS];
>   /*  to initlize semaphores operations */
>   dec.sem_op=-1,inc.sem_op=1,op.sem_op=EXETHREADS;
>      if( -1==(Start=semget('A',1,0666|IPC_CREAT)) ||
>           -1==(ReStart=semget('B',1,0666|IPC_CREAT))
>       ){perror("semget");return EXIT_FAILURE;}
>      /* to initilize semaphores value */
>   semctl(Start,0,SETVAL,0);
>   semctl(ReStart,0,SETVAL,0);
>   #ifndef linux    /* may be this string is not needed, I do not know*/
>   if(pthread_setconcurrency(MAXTHREADS+1))perror("concurrency");
> #endif

Not needed.  Also, it does not set errno, it returns the error value.
Use strerror().

>
>   /* to create the threads */
>   for(i=0;i<MAXTHREADS;++i)
>       pthread_create(thread+i,NULL,hand,s[i]);
>         for(i=0;i<ITERAT;++i){
>       puts("____START____");
>       semop(Start,&op,1);
>       /* to wait EXETHREADS threads */
>       op.sem_op*=-1;
>       /*
>           !!! this problem is here !!!
>                      if I insert 'pause()' or 'while(1)' instend of 
> 'semop(ReStart,&op,1)'
>           that only one thread is executed two time, why?
>                      this code does not help too (but I can see names that 
> is printed by hand())
>           op.sem_flg=IPC_NOWAIT
>           while(-1==semop(ReStart,&op,1) && EAGAIN);
>                  */
>       semop(ReStart,&op,1);
>       op.sem_op*=-1;
>              puts("____FINISH____");
>   }
>         /* to wait the threads to exit*/
>   semctl(Start,0,SETVAL,MAXTHREADS);
>   Exit=1;
>   for(i=0;i<MAXTHREADS;++i)
>       pthread_join(thread[i],NULL);
> 
>   if(    -1==semctl(ReStart,0,IPC_RMID) ||
>           -1==semctl(Start,0,IPC_RMID)
>       ) perror("semdel");
>          return EXIT_SUCCESS;
> }

Silently wondering why on earth anybody would want to use SYSV
semaphores to synchronize threads in the same program, I compiled and
ran your code on some different boxes:

   FreeBSD 5.3, i386           - runs ok (?)
   FreeBSD 5.3, sparc64        - hangs after first line of output
   Linux 2.6/Debian 3.1, i386  - hangs after last line of output
   Solaris 9, sparc64          - dumps core in semctl

I believe your program perhaps is not 100% correct... :-)

     $.02,
     /Mikko


More information about the freebsd-threads mailing list