题目:三个进程 a、b、c 分别输入“A”、“B”、“C”,要求输出结果必须是“ABCABCABC”
(一)分析
按照ABC的顺序打印的话,可以看到总共3个A、3个B、3个C,所以未同步之前的进程大致是这样:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
for(int i = 0; i < 3; i++)
{
write(1, "A", 1);
/*
* a进程输出A
* b进程输出B
* c进程输出C
*/
int num = rand() % 3;
sleep(num);
}
}
- 未同步试试运行结果:
(二)信号量同步思路
规定顺序的话,先A后B再C,后续循环也是如此,所以给定三个信号量如下图流程进行p v操作即可
(三)使用信号量同步后
- sem.h
#include <stdio.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
//信号量的个数
#define INDEXSIZE 3
union semun
{
int val; //信号量的值
};
//创建(获得)信号量集,并初始化信号量的值
void sem_init();
//对下标为index的信号量的p操作
void sem_p(int index);
//对下标为index的信号量的v操作
void sem_v(int index);
//销毁信号量集
void sem_destroy();
- sem.c
#include "sem.h"
//信号量集的ID 默认是-1
static int semid = -1;
//创建(获得)信号量集,并初始化信号量的值
void sem_init()
{
semid = semget((key_t)8888, 3, IPC_CREAT | IPC_EXCL | 0600);
//已经存在,创建失败
if(semid == -1)
{
//获取信号量集的ID
semid = semget((key_t)8888, 3, IPC_CREAT);
if(semid == -1)
{
perror("semget err");
return;
}
}
//初始化信号量
else
{
union semun arr[INDEXSIZE];
arr[0].val = 1;
arr[1].val = 0;
arr[2].val = 0;
for(int index = 0; index < INDEXSIZE; index++)
{
int ret = semctl(semid, index, SETVAL, arr[index]);
if(ret == -1)
{
perror("semctl setval err");
return;
}
}
}
}
//对下标为index的信号量的p操作
void sem_p(int index)
{
if(index < 0 || index > INDEXSIZE)
{
perror("index out of line");
return;
}
struct sembuf buf;
buf.sem_num = index;
buf.sem_op = -1;
buf.sem_flg = SEM_UNDO;
//对index对应的信号量进行p操作
if(semop(semid, &buf, 1) == -1)
{
perror("semop p err");
return;
}
}
//对下标为index的信号量的v操作
void sem_v(int index)
{
if(index < 0 || index > INDEXSIZE)
{
perror("index out of line");
return;
}
struct sembuf buf;
buf.sem_num = index;
buf.sem_op = 1;
buf.sem_flg = SEM_UNDO;
//对index对应的信号量进行v操作
if(semop(semid, &buf, 1) == -1)
{
perror("semop v err");
return;
}
}
//销毁信号量集
void sem_destroy()
{
if(semctl(semid, 0, IPC_RMID) == -1)
{
perror("sem_destroy err");
return;
}
}
- a.c
#include "sem.h"
int main()
{
sem_init();
for(int i = 0; i < 3; i++)
{
sem_p(0);
write(1, "A", 1);
sem_v(1);
int num = rand() % 3;
sleep(num);
}
return 0;
}
- b.c
#include "sem.h"
int main()
{
sem_init();
for(int i = 0; i < 3; i++)
{
sem_p(1);
write(1, "B", 1);
sem_v(2);
int num = rand() % 3;
sleep(num);
}
return 0;
}
- c.c
#include "sem.h"
int main()
{
sem_init();
for(int i = 0; i < 3; i++)
{
sem_p(2);
write(1, "C", 1);
sem_v(0);
int num = rand() % 3;
sleep(num);
}
sleep(1);
sem_destroy();
return 0;
}
- 结果: