#include<sys/sem.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int res; // 返回结果
int sem_id; //信号标识符
union semun //定义semun,不同的系统可能不同,需要自己定义
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
void sem_setval() //初始化信号量
{
union semun sem_union;
sem_union.val=1; //信号量的初始值
res=semctl(sem_id,0,SETVAL,sem_union); //初始化信号量
if(-1==res)
{
perror("semctl failed \n");
exit(0);
}
}
void sem_remove() //销毁信号量
{
union semun sem_union;
res=semctl(sem_id,0,IPC_RMID,sem_union); //销毁信号量
if(-1==res)
{
perror("sem remove control fail\n");
exit(0);
}
}
void sem_p() //减少信号量
{
struct sembuf sema_buff;
sema_buff.sem_num=0; //信号编号,信号量编号从0开始
sema_buff.sem_op=-1; //对信号量的操作值,使信号量减1
sema_buff.sem_flg=SEM_UNDO; //让系统跟进这个信号量的修改
res=semop(sem_id,&sema_buff,1);//对信号量操作,如果信号量为0则等待。
if(-1==res)
{
perror("semop failed \n");
exit(0);
}
}
void sem_v() //增加信号量
{
struct sembuf sema_buff;
sema_buff.sem_num=0;
sema_buff.sem_op=1; //使信号量加1
sema_buff.sem_flg=SEM_UNDO;
res=semop(sem_id,&sema_buff,1);
if(res==-1)
{
perror("semov failed\n");
exit(0);
}
}
int main()
{
char CHR; //这是本程序的临界变量,即一次只能一个进程或线程访问
sem_id=semget((key_t)1024,1,0666|IPC_CREAT);
if(sem_id<=0)
{
perror("semget failed\n");
exit(0);
}
sem_setval();
res=fork(); //创建新进程
if(res==-1)
{
perror("fork error\n");
exit(0);
}
if(res==0) //子进程
{
int i=0;
CHR='O';
for(i;i<=10;i++)
{
sem_p();
printf("%c",CHR);
fflush(stdout);
printf("%c",CHR);
fflush(stdout);
sleep(1);
sem_v();
}
exit(0);
}else{ //父进程
int i=0;
CHR='X';
for(i;i<=10;i++)
{
sem_p();
printf("%c",CHR);
printf("%c",CHR);
fflush(stdout);
sleep(1);
sem_v();
}
wait(NULL);
sem_remove();
exit(0);
}
}