`
jishublog
  • 浏览: 871065 次
文章分类
社区版块
存档分类
最新评论

Linux c 信号量

 
阅读更多

信号量(通过进程通信实现进程间的同步)

信号量(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进程的执行

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics