多线程信号量通讯
多线程间通过信号量通讯
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);
}