多线程信号量通讯
多线程间通过信号量通讯
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);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现