旗语:信号量
本质为一个整型数组
整数本身无意义,通过对数的数值检测后不同的操作来实现同步。
本质为一个整型数组
整数本身无意义,通过对数的数值检测后不同的操作来实现同步。
semaphore operations 旗语操作
A B
semop semop
编程模型
A B
创建key ftok 创建key
创建sem semget 得到旗语
初始化sem semctl SETVAL
操作旗语 semop 操作旗语
获取旗语信息 semctl IPC_STAT
删除旗语 semctl IPC_RMID
nattchs
0666
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(
key_t key, //key
int nsems, //旗语个数
int semflg);//方式
key_t key, //key
int nsems, //旗语个数
int semflg);//方式
创建nsems个旗语,这些旗语在key决定的内存段中保存,旗语是整数,整数的值不确定或者可能被linux os 初始化为0,但是这是不可靠的,应该初始化为一个有用的整数才是好程序员应该做的。
int semctl(
int semid,
int semnum,
int cmd,
...);
int semid,
int semnum,
int cmd,
...);
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int semop(
int semid, //操作的旗语
struct sembuf *sops,//操作方式
unsigned nsops);//操作次数
int semid, //操作的旗语
struct sembuf *sops,//操作方式
unsigned nsops);//操作次数
struct sembuf{
unsigned short sem_num; /*旗语下标*/
short sem_op; /*操作行为*/
short sem_flg; /*操作方式:0*/
};
unsigned short sem_num; /*旗语下标*/
short sem_op; /*操作行为*/
short sem_flg; /*操作方式:0*/
};
操作方式由结构体设置,一般是加减。
加会立刻成功,semop函数返回。
减有如下几种情况:
1.减少后旗语的值大于等于0,立刻减少,返回。
2.减少后旗语的值小于0,并且设置sem_flg为0,阻塞,等待减少后值大于0,转为情况1.
3.减少后旗语的值小于0,并且设置sem_flg为IPC_NOWAIT,失败,返回-1并设置错误输出缓冲区.
加会立刻成功,semop函数返回。
减有如下几种情况:
1.减少后旗语的值大于等于0,立刻减少,返回。
2.减少后旗语的值小于0,并且设置sem_flg为0,阻塞,等待减少后值大于0,转为情况1.
3.减少后旗语的值小于0,并且设置sem_flg为IPC_NOWAIT,失败,返回-1并设置错误输出缓冲区.
A
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//旗语值初始化需要用到的联合
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int main(){
//创建key
key_t key = ftok(".",88);
if(key == -1) printf("ftok error:%m\n"),exit(-1);
printf("ftok %m\n");
//创建旗语数组。数组中只有一个元素
int semid = semget(key,1,IPC_CREAT|0666);
if(-1 == semid) printf("semget error:%m\n"),exit(-1);
printf("semget %m\n");
union semun un;
un.val = 2;
//设置第一个旗语值为2
int r = semctl(semid,0,SETVAL,un);
if(r == -1) printf("sem init error:%m\n"),exit(-1);
printf("sem init %m\n");
//旗语操作行为结构体
struct sembuf sops;
sops.sem_num = 0;//控制旗语数组中第一个
sops.sem_op = -1;//每次-1
sops.sem_flg = 0;//阻塞方式
int i = 0;
while(1){
printf("sleep:%d!\n",i++);
semop(semid,&sops,1);//控制旗语,操作1次
printf("wake up and go on!\n");
}
return 0;
}
B
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main(){
key_t key = ftok(".",88);
if(key == -1) printf("ftok error:%m\n"),exit(-1);
printf("ftok %m\n");
int semid = semget(key,0,0);
if(-1 == semid) printf("semget error:%m\n"),exit(-1);
printf("semget %m\n");
struct sembuf sops;
sops.sem_num = 0;//控制旗语数组中第一个
sops.sem_op = +1;//每次-1
sops.sem_flg = 0;//阻塞方式
while(1){
sleep(1);
semop(semid,&sops,1);
}
return 0;
}