linux 网络 指示灯,linux之信号灯集

信号灯集是配合共享内存实现同步和互斥的机制。

1,创建信号灯集

semget();

2,初始化信号灯集的信号灯的值

semctl();

3;信号灯集的P操作

semop(int semid,sturct sembuf *opstr,size_t nops)

sturct sembuf *opstr为系统结构体

semid为信号灯集ID

struct sembuf{

short sem_num;

shirt sem_op:         0 等待

1 释放 V操作

-1 分配 P操作

short sem_flg     0  阻塞等待信号到来

IPC_NOWAIT  非阻塞不等待信号到来

SEM_LNDO 当前进程非法退出,把信号量的值还原到原先的状态

nops: 要操作的信号灯的个数

}

4,删除信号灯操作

int semctl(semid,int semnum IPC_RMID);   //IPC_RMID从系统中删除信号灯集合

read和write两个进程通信使用信号灯集配合共享内存的机制

read.c代码如下

#include #include #include #include #include #include #include

union semun {

int  val; /* Value for SETVAL */

struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */

unsigned short  *array; /* Array for GETALL, SETALL */

struct seminfo  *__buf; /* Buffer for IPC_INFO

(Linux-specific) */

};

int init_sem_value(int sem_id,int num,int value)

{

union semun var;

var.val = value;

if(semctl(sem_id,num,SETVAL,var) < 0)

{

perror("Fail to semctl");

exit(EXIT_FAILURE);

}

return 0;

}

//P操作

void P(int sem_id,int num)

{

struct sembuf buf;

buf.sem_num = num;

buf.sem_op = -1;

//SEM_UNDO  :值的是进程异常退出的时候,释放它申请的资源

//IPC_NOWAIT:没有申请到资源的时候,不阻塞,立即返回

//0         :阻塞方式

buf.sem_flg = 0;

if(semop(sem_id,&buf,1) < 0)

{

perror("Fail to semop");

exit(EXIT_FAILURE);

}

return ;

}

//V操作

void V(int sem_id,int num)

{

struct sembuf buf;

buf.sem_num = num;

buf.sem_op = 1;

//SEM_UNDO  :值的是进程异常退出的时候,释放它申请的资源

//IPC_NOWAIT:没有申请到资源的时候,不阻塞,立即返回

//0         :阻塞方式

buf.sem_flg = 0;

if(semop(sem_id,&buf,1) < 0)

{

perror("Fail to semop");

exit(EXIT_FAILURE);

}

return ;

}

//./a.out .

int main(int argc, const char *argv[])

{

char *addr;

int shm_id;

key_t key;

//先运行

if((key = ftok(argv[1],'k'))  < 0)

{

perror("Fail to key");

exit(EXIT_FAILURE);

}

printf("key = %#x.\n",key);

/*

*int shmget(key_t key, size_t size, int shmflg);

*第一个参数:

*1.IPC_PRIVATE,每次都会获得一个新的共享内存,主要用于有亲缘关系的进程

*2.通过ftok函数获得

* key_t key;

* key = ftok(pathname,字符);

*

*第二个参数:

*共享内存大小

*

*第三个参数:

*IPC_CREAT,IPC_EXCL,权限

*/

//如果对应的key的共享内存不存在,创建,然后返回其ID

//如果对应的key的共享内存存在,直接返回ID

if((shm_id = shmget(key,1024,IPC_CREAT | 0666)) < 0)

{

perror("Fail to shmget");

exit(EXIT_FAILURE);

}

printf("shm_id = %d.\n",shm_id);

//映射共享内存

if( (    addr = (char *)shmat(shm_id,NULL,0)   )   == (char *)-1  )

{

perror("Fail to shmat");

exit(EXIT_FAILURE);

}

//**************************信号灯集*******************

int sem_id;

//创建信号灯集

if((sem_id = semget(key,2,IPC_CREAT | IPC_EXCL | 0666) ) < 0)

{

if((sem_id = semget(key,2,IPC_CREAT | 0666)) < 0)

{

perror("Fail to semget");

exit(EXIT_FAILURE);

}

}else{

//初始化信号灯集信号灯的值

init_sem_value(sem_id,0,0);

init_sem_value(sem_id,1,1);

}

while(1)

{

P(sem_id,0);

printf("%s.\n",addr);

V(sem_id,1);

if(strncmp(addr,"quit",4) == 0)

break;

}

//解除映射

if(shmdt(addr) < 0)

{

perror("Fail to shmdt");

exit(EXIT_FAILURE);

}

exit(EXIT_SUCCESS);;

}

write.c代码如下:

#include #include #include #include #include #include #include

union semun {

int  val; /* Value for SETVAL */

struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */

unsigned short  *array; /* Array for GETALL, SETALL */

struct seminfo  *__buf; /* Buffer for IPC_INFO

(Linux-specific) */

};

int init_sem_value(int sem_id,int num,int value)

{

union semun var;

var.val = value;

if(semctl(sem_id,num,SETVAL,var) < 0)

{

perror("Fail to semctl");

exit(EXIT_FAILURE);

}

return 0;

}

//P操作

void P(int sem_id,int num)

{

struct sembuf buf;

buf.sem_num = num;

buf.sem_op = -1;

//SEM_UNDO  :值的是进程异常退出的时候,释放它申请的资源

//IPC_NOWAIT:没有申请到资源的时候,不阻塞,立即返回

//0         :阻塞方式

buf.sem_flg = 0;

if(semop(sem_id,&buf,1) < 0)

{

perror("Fail to semop");

exit(EXIT_FAILURE);

}

return ;

}

//V操作

void V(int sem_id,int num)

{

struct sembuf buf;

buf.sem_num = num;

buf.sem_op = 1;

//SEM_UNDO  :值的是进程异常退出的时候,释放它申请的资源

//IPC_NOWAIT:没有申请到资源的时候,不阻塞,立即返回

//0         :阻塞方式

buf.sem_flg = 0;

if(semop(sem_id,&buf,1) < 0)

{

perror("Fail to semop");

exit(EXIT_FAILURE);

}

return ;

}

//./a.out .

int main(int argc, const char *argv[])

{

char *addr;

int shm_id;

key_t key;

//先运行

if((key = ftok(argv[1],'k'))  < 0)

{

perror("Fail to key");

exit(EXIT_FAILURE);

}

printf("key = %#x.\n",key);

/*

*int shmget(key_t key, size_t size, int shmflg);

*第一个参数:

*1.IPC_PRIVATE,每次都会获得一个新的共享内存,主要用于有亲缘关系的进程

*2.通过ftok函数获得

* key_t key;

* key = ftok(pathname,字符);

*

*第二个参数:

*共享内存大小

*

*第三个参数:

*IPC_CREAT,IPC_EXCL,权限

*/

//如果对应的key的共享内存不存在,创建,然后返回其ID

//如果对应的key的共享内存存在,直接返回ID

if((shm_id = shmget(key,1024,IPC_CREAT | 0666)) < 0)

{

perror("Fail to shmget");

exit(EXIT_FAILURE);

}

printf("shm_id = %d.\n",shm_id);

//映射共享内存

if( (    addr = (char *)shmat(shm_id,NULL,0)   )   == (char *)-1  )

{

perror("Fail to shmat");

exit(EXIT_FAILURE);

}

//**************************信号灯集*******************

int sem_id;

//创建信号灯集

if((sem_id = semget(key,2,IPC_CREAT | IPC_EXCL | 0666) ) < 0)

{

if((sem_id = semget(key,2,IPC_CREAT | 0666)) < 0)

{

perror("Fail to semget");

exit(EXIT_FAILURE);

}

}else{

//初始化信号灯集信号灯的值

init_sem_value(sem_id,0,0);

init_sem_value(sem_id,1,1);

}

while(1)

{

P(sem_id,1);

fgets(addr,1024,stdin);

V(sem_id,0);

if(strncmp(addr,"quit",4) == 0)

break;

}

//解除映射

if(shmdt(addr) < 0)

{

perror("Fail to shmdt");

exit(EXIT_FAILURE);

}

//删除共享内存对象

//真正删除:在共享内存映射次数为0的时候,才会删除

if(shmctl(shm_id,IPC_RMID,NULL) < 0)

{

perror("Fail to shmctl");

exit(EXIT_FAILURE);

}

usleep(500);

//删除信号灯集合

if(semctl(sem_id,0,IPC_RMID) < 0)

{

perror("Fail to semctl");

exit(EXIT_FAILURE);

}

exit(EXIT_SUCCESS);;

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值