#include<stdio.h>
#include<stdlib.h>
#include<sys/sem.h>
// 自用共用体
union semu
{
/* data */
int val;
struct semid_ds* buf;
unsigned short* array;
struct seminfo* _buf;
};
static int sem_id;
//设置信号量值
static int set_semvalue(){
union semu sem_union;
sem_union.val = 1;
if (semctl(sem_id, 0, SETVAL, sem_union)== -1){
return 0;
}
return 1;
}
// P 操作,获取信号量
static int semaphore_p(){
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1)==-1){
perror("sem_p error");
return 0;
}
return 1;
}
// V 操作,释放信号量
static int semaphore_v(){
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1)==-1){
perror("sem_v error");
return 0;
}
return 1;
}
// 删除信号量
static void del_semvalue(){
union semu sem_union;
if (semctl(sem_id, 0, IPC_RMID, sem_union)==-1){
perror("del error");
}
}
int main(int argc, char* argv[]){
int i;
pid_t pid;
char ch='C';
sem_id = semget((key_t)1000, 1, 0664|IPC_CREAT); // 创建信号量 信号量数目是1
if (sem_id == -1) {
perror("sem_create error");
exit(-1);
}
if (!set_semvalue()){ // 设置信号量值
perror("init error");
exit(-1);
}
pid = fork();
if (pid ==-1){
// 删除信号量
del_semvalue();
exit(-1);
}else if (pid == 0){
ch = 'Z'; // 设置子进程打印的字符
}else {
ch = 'C'; // 设置父进程打印的字符
}
srand((unsigned int)getpid()); // 设置随机数种子
for (i = 0; i < 8; i++)
{
semaphore_p(); // 获取信号量
printf("%c", ch);
fflush(stdout); // 将字符打印到屏幕上
sleep(1);
printf("%c", ch);
fflush(stdout);
sleep(1);
semaphore_v();
}
if (pid>0) {
wait(NULL);
del_semvalue();
}
printf("\nprocess %d finished\n", getpid());
return 0;
}
输出如下:
zfz:Demo zhangfengzhou$ gcc sem.c -o sem
zfz:Demo zhangfengzhou$ ./sem
CCCCCCCCCCCCCCCCZZZZZZZZZZZZZZZZ
process 48974 finished