使用信号量同步来自不同进程的线程

时间:2019-05-04 14:20:22

标签: c linux multithreading semaphore

我在C语言中遇到信号量问题。我有一个父进程和一个子进程。两者都可以创建3个线程,并且我必须显示线程的开始和结束,并且必须施加下一个条件:父进程ID为1的线程必须在子进程ID为2的线程结束之后显示其开头。我使用了信号灯,但是当我等待时,来自父进程的ID为1的线程不会停留在信号灯上并继续显示开始。我不能使用函数usleep()或sleep()。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include <semaphore.h>


sem_t* s=NULL;

void* function1(void* arg)
{
   int* nrth=(int*) arg;
   sem_t   * s=NULL;

   s=sem_open("mysemaphore",O_EXCL);
   if(s==NULL)
       perror("Error");

   if(*nrth==1)
       sem_wait(s);


   printf("Begin P1, thread %d\n",*nrth);
   printf("End P1, thread %d\n",*nrth);


   sem_close(s);
   return 0;

}



void* function2(void* arg)
{
    int* nrth=(int*) arg;

    sem_t   * s=NULL;
    s=sem_open("mysemaphore",O_EXCL);
    if(s==NULL)
        perror("Error");

    printf("Begin P2, thread %d\n",*nrth);
    printf("End P2, thread %d\n",*nrth);

    if(*nrth==2)
       sem_post(s);

    sem_close(s);

    return 0;
}


int main()
{
   sem_unlink("mysemaphore");
   s=sem_open("mysemaphore",O_CREAT,0644,1);
   if(s==NULL)
      perror("ERROR!");


   pthread_t threads[4];
   int index[4];
   pthread_t threads2[4];
   int index2[4];

   if(fork()==0)
   {

      printf("Begin: process 2 \n");

       for(int i=1; i<=3; i++)
       {
          index2[i]=i;
          pthread_create(&threads2[i],NULL,function2,&index2[i]);
       }
       for(int i=1; i<=3; i++)
       {
          pthread_join(threads2[i],NULL);
       }
       printf("End: process 2 \n");
   }
   else
   {
       printf("Begin: process 1\n");

       for(int i=1; i<=3; i++)
       {
          index[i]=i;
          pthread_create(&threads[i],NULL,function1,&index[i]);
       }

       for(int i=1; i<=3; i++)
       {
           pthread_join(threads[i],NULL);
       }
       printf("End: process 2 \n");

       wait(NULL);
   }
   return 0;
}

1 个答案:

答案 0 :(得分:1)

调用function1()时,您将同时破坏function2()sem_destroy()中的信号量,此后该信号量的行为是不确定的。那可能是您最大的问题。

在使用完从sem_close()获得的信号后,应该使用sem_open()