信号量(通过进程通信实现进程间的同步)
信号量(semaphore)信号灯
信号量是共享内存整数数组.根据需要定义指定的数组长度
信号量就是根据数组中的值,决定阻塞还是解除阻塞
编程模型:
1. 创建或者得到信号量 semget
2. 初始化信号量中指定下标的值 semctl
3. 根据信号量阻塞或者解除阻塞 semop
4. 删除信号量 semctl
案例:
A: B:
创建信号量 得到信号量
初始化信号量 解除阻塞
根据信号量阻塞
删除信号量
int semget(key_t key,
int nums,//信号量数组个数
int flags);//信号量的创建标记
//创建IPC_CREAT|IPC_EXCL|0666
//打开0
返回: -1:失败
>=0:成功返回信号量的ID
int semctl(int semid,
intnums,//对IPC_RMID无意义
intcmd,//SETVAL(信号量值)IPC_RMID
...);//对IPC_RMID无意义
参数:
semid:信号集的标识符,即是信号表的索引。
semnum:信号集的索引,用来存取信号集内的某个信号。
cmd:需要执行的命令,有效值有 需要使用联合体semun赋值
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *_buf;
};//需要自己定义该联合体,根据需要定义,需要那个字段就可以只定义那个
int semop(
int semid,//信号量ID
struct sembuf*op,//对信号量的操作.操作可以是数组多个
size_tnums,//第二个参数的个数
);
返回:
-1:时失败
0:成功
struct sembuf
{
int sem_num;//下标
int sem_op;
int sem_flg;//建议为0.
}
sem_op:
前提条件信号量是unsigned short int;
不能<0.
-:够减,则semop马上返回,不够减,则阻塞.
+:执行+操作
0:判定信号量>0,则阻塞,直到为0
控制进程的搭配方式:
+(解除阻塞) -(阻塞)
0(阻塞) -(解除阻塞)
代码:
semA:
#include<stdio.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<stdlib.h>
#include<signal.h>
int semid;
void deal(ints)
{
//4.删除信号量
printf(“删除信号量…”);
semctl(semid,0,IPC_RMID , 0);
printf(“信号量已删除”);
exit( -1 );
}
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *_buf;
};
void main()
{
key_tkey;
union semun v;//2.2定义初始化值
int r;
//3.1定义一个操作结构体
structsembuf op[1]; //定义了两个操作
signal(SIGINT , deal);
//1.创建信号量
key=ftok(“.” , 99);
if(key == -1) printf(“ftok err :%m\n”) ,exit(-1);
semid=semget(kay,1 /*信号量数组个数*/ , IPC_CREAT | IPC_EXCL | 0666);
if( semget == -1) printf(“get err %m\n”) ,exit(-1);
//2.初始化信号量
//2.1定义一个联合体
v.val=2;
r=semctl(semid , 0 , SETVAL , v); //设置信号量的值
if(r== -1) printf(“初始化失败:%m\n”) , exit(-1);
//3.对信号量阻塞操作
op[0].sem_num=0; //信号量的下标
op[0].sem_op= 1; //信号量操作单位与类型
op[0].sem_flg=0; //操作标记 IPC_NOWAIT(信号量值够不够减都返回 不阻塞)
//SEM_UNDO 建议为0;
while(1)
{
r=semop(semid , op ,1);
printf(“信号量阻塞-1”);
}
}
//semop操作减一 ,信号量值大于0,semop执行返回,信号量值等于0时,semop操作阻塞等待,直到信号量值大于0,在进行该操作
semB:
#include<stdio.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<stdlib.h>
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *_buf;
};
void main()
{
intsemid;
key_tkey;
int r;
//3.1定义一个操作结构体
structsembuf op[1]; //定义了两个操作
signal(SIGINT , deal);
//1.得到信号量
key=ftok(“.” , 99);
if(key == -1) printf(“ftok err :%m\n”) ,exit(-1);
semid=semget(kay,1 /*信号量数组个数*/ ,0);
if( semget == -1) printf(“get err %m\n”) ,exit(-1);
//3.对信号量阻塞操作
op[0].sem_num=0; //信号量的下标
op[0].sem_op= +1; //信号量操作单位与类型
op[0].sem_flg=0; //操作标记 IPC_NOWAIT(信号量值够不够减都返回 不阻塞)
//SEM_UNDO 建议为0;
while(1)
{
r=semop(semid , op ,1);
sleep(1);
}
}
//进程semA进行信号量阻塞-1 semB进行信号量接触阻塞+1 , semB进程控制semA进程的执行
分享到:
相关推荐
关于linux c 开发中的信号量的使用,有详细的说明
在Linux环境下实现一个多线程对临界资源的互斥操作,利用信号量实现对临界资源的保护,支持Linux下文件输入输出,提高对Linux环境下多进程、多线程、信号量机制和文件操作等知识的理解。 设有进程A、B、C,分别调用...
Linux 下C++共享内存、信号量封装,实现进程同步
多进程之间的互斥信号量的实现(Linux和windows跨平台)
linux下多任务的信号量集实现,花了哥两周的时间。
信号量所为一种线程安全对象,在多线程...c语言做多线程开发,实现一个跨平台信号量对象还是有用的。 本资源在Windows、Linux、Android、IOS都可以使用 https://blog.csdn.net/u013113678/article/details/120464391
linux多任务(进程)同步-信号量集
linux下共享内存+信号量,不会出奇怪的错误,如信号量和共享内存未清,导致无法再次运行,ctrl+c后能够正常清除信号量及共享内存。
linux系统c语言实现爸爸儿子女儿简单消费者问题苹果橘子拿与放问题, 资源共享,线程互斥,使用简单的无名信号量解决
linuxC语言描述操作系统入门基础 多进程 socket 信号量 管道
C语言编写程序,用信号量和共享内存实现读写同步,程序中父进程为读进程,子进程为写进程。开启共享内存空间和二值信号量,子进程占用信号量,父进程无法执行读,等待子进程写完释放信号量后父进程进行读操作。依次...
linux下system V信号量的C语言封装,及其示例代码,用于进程间通信。
操作系统初学,关于信号量同步的实验报告,用三种方法避免哲学家进餐问题死锁,a:and信号量,b:控制进餐人数,c设置条件
Linux信号量线程控制--培训教程.pdf 亚嵌培训教程,绝对经典。
代码实现了共享内存和信号量的结合,实现进程间通信及其同步问题。通过此代码可以理解共享内存及信号量基本函数的使用及实现原理。
(自制)俄罗斯方块c语言版,用printf语句实现,使用了信号量实现自动下落。(只能在linux环境下运行) 上:变型 下:加速下落 左右:移动 回车:直接下落底部 空格:暂停,继续 q:退出
巨好用,让你充分了解信号量!着重linux0.11方面
这个实验花了我4天,做出来对操作系统的理解真的就不一样了好多,内容是关于信号量的实现的。整个这套上传的操作系统实验实验3也许不能直接运行成,其余都是直接可以运行的。这个是07级哈尔滨工业大学操作系统实验的...
②linux系统编程学习:C语言进程、信号、线程、线程锁、进程锁、信号量; ③linux网络编程学习:tcp编程、udp编程(socket套接字编程); ④linux-shell编程学习; 资源几乎包含了博主的整个linux学习的资料,是根据...
用c语言写的模拟信号量 互斥量 消息队列等线程通讯机制的程序,用来加深对线程通讯的理解