多线程信号量通讯

多线程间通过信号量通讯

int semget(key_t key, int nsems, int semflg);

int semop(int semid, struct sembuf *sops, size_t nsops);

int semctl(int semid, int semnum, int cmd, ...);

示例:sem.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
#include <unistd.h>

#define PTHNUM 20      //定义线程个数
#define BUFFSIZE 1024
static int semid;

static void P(void)     //P操作(信号量减一)
{
  struct sembuf set;

  set.sem_num = 0;     //指定是信号量数组的哪一个信号量
  set.sem_op = -1;  //指定操作减一
  set.sem_flg = 0;       //无特定要求

  semop(semid,&set,1);    //将信息设置到信号量数组中(信号量ID,信号量信息地址,每次操作的信号量个数)
}

static void V(void)
{
  struct sembuf set;

  set.sem_num = 0;  //指定是信号量数组的哪一个信号量
  set.sem_op = 1;     //指定操作加一
  set.sem_flg = 0;     //无特殊要求

  semop(semid,&set,1);  //将信息设置到信号量数组中(信号量ID,信号量信息地址,每次操作的信号量个数)
}

static void *add(void *p)
{
  FILE *fp;
  char buff[BUFFSIZE];

  fp = fopen("/tmp/out","r+");   //读写方式打开文件
  if(fp ==NULL)
  {
    perror("fopen()");
    exit(1);
  }

  P();            //P操作请求信号量
  fgets(buff,BUFFSIZE,fp);    //读取文件内容
  fseek(fp,0,SEEK_SET);     //定位到文件头
  sleep(1);            //测试语句
  fprintf(fp,"%d\n",atoi(buff)+1);    //输出到文件
  fflush(fp);           //刷新文件数据流
  V();            //V操作释放请求的信号量

  fclose(fp);        //关闭文件

  pthread_exit(NULL);    //退出线程
}

int main()
{
  pthread_t tid[PTHNUM];
  int i,ret;

  while((semid = semget(IPC_PRIVATE,1,0600)) <0 )   //申请信号量ID(key值,信号量数组大小,权限)
  {
    if(errno == EINTR)
      continue;
    perror("semget()");
    exit(1);
  }

  semctl(semid,0,SETVAL,1);    //设置信号量   (信号量ID,信号数组中的哪一个信号,具体操作,操作的参数)

  for(i=0;i<PTHNUM;i++)
  {
    ret = pthread_create(&tid[i],NULL,add,NULL);   //循环创建线程
    if(ret !=0)
    {
      printf("pthread_create error\n");
      exit(1);
    }
  }

  for(i=0;i<PTHNUM;i++)   //等待线程结束
  {
    pthread_join(tid[i],NULL);
  }
  semctl(semid,0,IPC_RMID);  //销毁信号量

  exit(0);
}

posted @ 2022-08-05 08:23  *^VV^*  阅读(35)  评论(0编辑  收藏  举报