您的位置:首页 > 运维架构 > Linux

linux的ipc信号量简单实例

2015-07-14 12:57 477 查看
信号量实现进程间访问互斥的资源测试例子。

主要涉及到的函数及原型如下(加粗、颜色表示要重点关心的上下文相关变量)

1: key_tftok(char *fileName, int id);//目的获取key值

2: intsemget(key_t key, int nsems, int semflg)//目的获取id

3:int semctl(int semid, int semnum, int cmd, union semunarg)//目的设置信号量的值,获取信号量的值等等,功能通过cmd变量控制

//其中semunarg必须由用户自身定义,格式如下

union semun {

int val;

struct semid_ds *buf;

unsigned short *array;

struct seminfo *__buf;

//other linux specific

};

4: int semop(int semid, struct sembuf *sops, unsign ednsops)//目的改变信号量的值,在sembuf中。

可通过每个函数大体功能,man手册中查找一些说明,进行研究测试。

以下测试代码非常简单,仅仅是为了熟悉api的基本功能,如果有错误和需要说明的地方,欢迎指正。

#include <sys/types.h>

#include <sys/sem.h>

#include <stdio.h>

#include <errno.h>

#include <sys/shm.h>

#include <stdlib.h>

#include <unistd.h>

union semun {//semctl函数的第三个参数结构定义,现只关心设置val,其它成员可忽视,起到初始化资源数目的作用

int val;

// struct semid_ds *buf;

// unsigned short *array;

// struct seminfo *__buf;

};

int sem_init(int semid, int initval)//初始化信号量 init val

{

union semun arg;

arg.val = initval;

semctl(semid, 0, SETVAL, arg);//SETVAL 是semctl的cmd参数,意思是设置信号量为arg.val的值,0是信号量中第1个资源的下标

//fixme if some error

return 0;

}

int creat_sem(char *fileName)//创建一个信号灯,信号量默认写了1个,如果没有该信号量,创建,如果有,获取id

{

int id;

key_t key;

key = ftok(fileName, 1);

if (key < 0) {

perror("ftok()");

key = 5;//any number just for test

}

if ((id = semget(key, 1, IPC_CREAT | IPC_EXCL |0660)) < 0) {//1个信号量 creat? or exist?

if ((id = semget(key, 1, IPC_CREAT | 0660)) < 0) {//1个信号量 if exist,only get the id

printf("semget error: id = %d\n", id);

}

printf("sem allready exist: id = %d\n", id);

} else {//init the number when first use

sem_init(id, 0);

}

return id;

}

void P(int semid)//申请资源,资源数sembuf中的sem_op - 1

{

int ret = 0;

struct sembuf sb;

sb.sem_num = 0;

sb.sem_op = -1;

sb.sem_flg = 0;

ret = semop(semid, &sb, 1);

if (ret < 0) {

printf("error in p(s)\n");

}

}

void V(int semid)//释放资源,资源数sembuf中的sem_op - 1

{

int ret = 0;

struct sembuf sb;

sb.sem_num = 0;

sb.sem_op = 1;

sb.sem_flg = 0;

ret = semop(semid, &sb, 1);

if (ret < 0) {

printf("error in v(s)\n");

}

}

void showStat(int semid)

{

int ret = semctl(semid, 0, GETVAL, 0);

printf("now %d val is %d\n", semid, ret);

}

int main(int argc, char **argv)

{

int sem_id0, sem_id1;

if (fork() == 0) {//子进程 进程1

sem_id0 = creat_sem("/tmp/2");

sem_id1 = creat_sem("/tmp/3");

V(sem_id1);

while (1) {

P(sem_id0);

printf("working : process11111\n");

showStat(sem_id0);

showStat(sem_id1);

sleep(1);

V(sem_id1);

}

} else {//父进程 进程2

sem_id0 = creat_sem("/tmp/2");

sem_id1 = creat_sem("/tmp/3");

sleep(2);

while (1) {

P(sem_id1);

printf("working : process2222222222\n");

showStat(sem_id0);

showStat(sem_id1);

sleep(2);

V(sem_id0);

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: