deadlock

Alexander Bubnov ab_fatal at mail.ru
Fri Nov 26 04:38:24 PST 2004


/*
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

    /* 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;
}



More information about the freebsd-threads mailing list