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>
