#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/sem.h>
#include<sys/ipc.h>
#include<unistd.h>
int semid;
//共享变量记录每次累加的结果
int a=0;
typedef union senum{
int val;//SETVAL用的值
struct semid_ds *buf;//IPC_STAT IPC_SET用的semind_ds结构
unsigned short *array;//SETALL GETALL用的数组值
struct seminfo *_buf;//为控制IPC_INFO提供的缓存
}arg;
//对信号量数据semnum编号的信号量做P操作
void P(int semid,int index)
{
struct sembuf sem;
sem.sem_num = index;//信号在信号集中的索引,0代表第一个信号,1代表第二个信号
sem.sem_op = -1;//操作类型
sem.sem_flg = 0; //操作标志
semop(semid,&sem,1);
}
//对信号量数组semnum编号的信号量做V操作
void V(int semid,int index)//V操作
{
struct sembuf sem;
sem.sem_num = index;
sem.sem_op = 1;
sem.sem_flg = 0;
semop(semid,&sem,1);//操作信号
}
void* thread1()//线程1运行函数
{
int i=1;
for(;i<=100;i++)
{
P(semid,0);
a+=i;
printf("Thread1=%d\n",a);//打印结果
V(semid,1);
}
}
void* thread2()//线程2运行函数
{
int i = 0;
for(;i<100;i++)
{
P(semid,1);
printf("a=%d\n",a);//打印结果
V(semid,0);
}
}
int main()
{
pthread_t id1,id2;//线程id号
int th1,th2;
arg arg1;
arg arg2;
semid=semget(1,2,IPC_CREAT|0666);//创建信号量集 第一个参数为0表示建立新的信号量对象
//0-32位整数:由参数semflg来确定操作
//IPC_CREAT|0666 确定信号量集的存取权限
//0666 -- 信号量的访问掩码
arg1.val=1;//初始时互斥信号为1,允许一个进程进入 第一次没有执行累加操作不能输出
arg2.val=0;//初始时缓冲区中无数据 阻塞等待信号量为0,调用进程进入睡眠状态,知道信号值为1
//初始化信号量集
semctl(semid,0,SETVAL,arg1);//对信号量0设置初始值
semctl(semid,1,SETVAL,arg2);//对信号量1设置初始值
//创建线程
th1=pthread_create(&id1,NULL,thread1,NULL);//返回值为0表示创建成功,否在 创建失败
if(th1!=0){//创建失败
return 0;
}
th2=pthread_create(&id2,NULL,thread2,NULL);
if(th2!=0){//创建失败
return 0;
}
//等待线程结束
pthread_join(id1,NULL);
pthread_join(id2,NULL);
semctl(semid,0,IPC_RMID,arg1);
semctl(semid,1,IPC_RMID,arg2);
return 0;
}
线程控制与同步linux实验
最新推荐文章于 2023-05-14 17:09:44 发布