一.信号量(用于同步)
1.回顾:
一个进程控制另外一个进程.
逻辑变量+pause/sleep+信号(前面章节 键盘控制随机数的例子)
2.信号量(semaphore)信号灯
三个数据:红灯/绿灯/黄灯
信号量是共享内存整数数组.根据需要定义指定的数组长度
信号量就是根据数组中的值,决定阻塞还是解除阻塞
3.编程模型
3.1.创建或者得到信号量 semget (可用ipcs -s 来查看信号量)
3.2.初始化信号量中指定下标的值 semctl
3.3.根据信号量阻塞或者解除阻塞 semop
3.4.删除信号量 semctl
案例:
A: B
创建信号量 得到信号量
初始化信号量
根据信号量阻塞 解除阻塞
删除信号量
semget函数说明
int semget(key_t key,
int nums,//信号量个数
int flags);//信号量的创建标记
//创建IPC_CREAT|IPC_EXCL|0666
//打开0
返回: -1:失败
>=0:成功返回信号量的ID
int semop(
int semid,//信号量ID
struct sembuf *op,//对信号量的操作.操作可以是多个
size_t nums,//第二个参数的个数
);
返回:
-1:时失败
0:成功
int semctl(int semid,
int nums,//对IPC_RMID无意义
int cmd,//SETVAL IPC_RMID
...);//对IPC_RMID无意义
struct sembuf
{
int sem_num;//下标
int sem_op;
int sem_flg;//建议为0.
}
sem_op:
前提条件信号量是unsigned short int;
不能<0.
-:够减,则semop马上返回,不够减,则阻塞.
+:执行+操作
0:判定信号量>0,则阻塞,直到为0
控制进程的搭配方式:
+(解除阻塞) -(阻塞)
0(阻塞) -(解除阻塞) 可实现双向通信
semB.c 每隔一秒对信号量加一解除阻塞
1.回顾:
一个进程控制另外一个进程.
逻辑变量+pause/sleep+信号(前面章节 键盘控制随机数的例子)
2.信号量(semaphore)信号灯
三个数据:红灯/绿灯/黄灯
信号量是共享内存整数数组.根据需要定义指定的数组长度
信号量就是根据数组中的值,决定阻塞还是解除阻塞
3.编程模型
3.1.创建或者得到信号量 semget (可用ipcs -s 来查看信号量)
3.2.初始化信号量中指定下标的值 semctl
3.3.根据信号量阻塞或者解除阻塞 semop
3.4.删除信号量 semctl
案例:
A: B
创建信号量 得到信号量
初始化信号量
根据信号量阻塞 解除阻塞
删除信号量
semget函数说明
int semget(key_t key,
int nums,//信号量个数
int flags);//信号量的创建标记
//创建IPC_CREAT|IPC_EXCL|0666
//打开0
返回: -1:失败
>=0:成功返回信号量的ID
int semop(
int semid,//信号量ID
struct sembuf *op,//对信号量的操作.操作可以是多个
size_t nums,//第二个参数的个数
);
返回:
-1:时失败
0:成功
int semctl(int semid,
int nums,//对IPC_RMID无意义
int cmd,//SETVAL IPC_RMID
...);//对IPC_RMID无意义
struct sembuf
{
int sem_num;//下标
int sem_op;
int sem_flg;//建议为0.
}
sem_op:
前提条件信号量是unsigned short int;
不能<0.
-:够减,则semop马上返回,不够减,则阻塞.
+:执行+操作
0:判定信号量>0,则阻塞,直到为0
控制进程的搭配方式:
+(解除阻塞) -(阻塞)
0(阻塞) -(解除阻塞) 可实现双向通信
semA.c 对信号量减一 阻塞
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//2.1.必须手工定义这个联合体
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
main()
{
key_t key;
int semid; //信号量ID
union semun v;//2.2.定义初始化值
int r;
struct sembuf op[1];
//<span style="color:#FF0000;">1.创建信号量</span>
key=ftok(".",99);
if(key==-1) printf("ftok err:%m\n"),exit(-1);
//semid=semget(key,1/*信号量数组个数*/,
// IPC_CREAT|IPC_EXCL|0666);//反复创建会失败 也可以在上面先删除
semid=semget(key,1,0);//得到信号量
if(semid==-1) printf("get err:%m\n"),exit(-1);
printf("id:%d\n",semid);
//<span style="color:#FF0000;">2.初始化信号量</span>
v.val=2;
r=semctl(semid,0,SETVAL,v);//2.3设置信号量的值
if(r==-1) printf("初始化失败!\n"),exit(-1);
//<span style="color:#FF0000;">3.对信号量进行阻塞操作</span>
//3.1.定义操作
op[0].sem_num=0;//信号量下标
op[0].sem_op=-1;//信号量操作单位与类型
op[0].sem_flg=0;
while(1)
{
r=semop(semid,op,1);
printf("解除阻塞!\n");
}
//4.<span style="color:#FF0000;">删除信号量</span>(可以不删除)
}
semB.c 每隔一秒对信号量加一解除阻塞
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//2.1.定义一个联合体
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
main()
{
key_t key;
int semid; //信号量ID
union semun v;//2.2.定义初始化值
int r;
struct sembuf op[1];
//1.<span style="color:#FF0000;">创建信号量</span>
key=ftok(".",99);
if(key==-1) printf("ftok err:%m\n"),exit(-1);
semid=semget(key,1,0);//得到信号量
if(semid==-1) printf("get err:%m\n"),exit(-1);
printf("id:%d\n",semid);
<span style="color:#FF0000;">//3.对信号量进行操作</span>
//3.1.定义操作
op[0].sem_num=0;//信号量下标
op[0].sem_op=1;//信号量操作单位与类型
op[0].sem_flg=0;
while(1)
{
r=semop(semid,op,1);
sleep(1);
}
//4.删除(可以不删除)
//semctl(semid,0,IPC_RMID);
}