Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Nov 2004 14:42:39 -0800 (PST)
From:      =?ISO-8859-1?Q?Mikko_Ty=F6l=E4j=E4rvi?= <mbsd@pacbell.net>
To:        Alexander Bubnov <ab_fatal@mail.ru>
Cc:        freebsd-threads@freebsd.org
Subject:   Re: deadlock
Message-ID:  <20041126143048.U9837@sotec.home>
In-Reply-To: <41A72410.9080500@mail.ru>
References:  <41A72410.9080500@mail.ru>

next in thread | previous in thread | raw e-mail | index | archive | help

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041126143048.U9837>