进程间通信之信号量

信号量:相当于一个计数器,描述当前环境下临界资源的数目。信号量是用来保护临界资源的,而信号量本身也是临界资源。

生命周期:随内核。

原子性:即要么做,要么不做。

临界资源:不同进程可以看到的同一资源。

临界区:不同进程访问同一资源的代码区(write(),read())。

互斥:任一时刻,只有一个进程进入临界区访问临界资源,且访问时具有原子性。

同步:所有进程以某种顺序依次访问临界资源。

信号量的两个基本操作:P、V操作-----解决互斥和同步的问题。

P操作:申请资源,如果S>0,则S=S-1;如果S = 0,就挂起该进程的执行。

V操作:使用资源完毕,归还给系统,若有进程挂起,则唤醒等待进程,否则S=S+1。

代码如下:

 
 
comm.h:
#ifndef _COMM_H
#define _COMM_H
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#define PATHNAME "."
#define PROJ_ID 0666
union semun{
int val;
struct semid_ds *buf;
unsigned short * array;
struct seminfo *__buf;
};
//struct sembuf{
// unsigned short sem_num; // semaphore number
// short sem_op; // semaphore operation
// short sem_flg; //operation flags
//};
int create_sem(int nsem);
int get_sem();
int destroy_sem(int semid);
int init_sem(int semid,int which,int val);
int P(int semid,int which);
int V(int semid,int which);
#endif
comm.c:
#include"comm.h"
static int comm_sem(int nsem ,int flag)
{
key_t key=ftok(PATHNAME,PROJ_ID);
int semid=semget(key,nsem,flag);
if(semid< 0){
perror( "semget");
}
return semid;
}
static op_sem(int semid,int op,int which)
{
struct sembuf _sembuf;
_sembuf.sem_op = op;
_sembuf.sem_num = which;
_sembuf.sem_flg = 0;
return semop(semid,&_sembuf, 1);
}
int create_sem(int nsem)
{
return comm_sem(nsem,IPC_CREAT|IPC_EXCL| 0666);
}
int get_sem()
{
return comm_sem( 0,IPC_CREAT);
}
int destroy_sem(int semid)
{
if(semctl(semid, 0,IPC_RMID)< 0)
{
perror( "semctl");
return - 1;
}
//printf("destroy sucess");
return 0;
}
int init_sem(int semid,int which,int _val)
{
union semun _semun;
_semun.val = _val;
if(semctl(semid,which,SETVAL,_semun)< 0)
{
perror( "semctl");
return - 2;
}
return 0;
}
int P(int semid,int which)
{
return op_sem(semid,- 1,which);
}
int V(int semid,int which)
{
return op_sem(semid, 1,which);
}
sem.c:
#include"comm.h"
#include<stdlib.h>
int main()
{
int semid=create_sem( 10);
init_sem(semid, 0, 1);
pid_t id=fork();
if(id< 0)
{
perror( "fork");
return - 1;
}
else if(id == 0){ //child
int sem_id=get_sem();
while( 1)
{
P(sem_id, 0);
printf( "A");
fflush( stdout);
usleep( 12345);
printf( "A");
fflush( stdout);
usleep( 13456);
V(sem_id, 0);
}
exit( 0);
}
else{ //father
while( 1)
{
P(semid, 0);
printf( "B");
fflush( stdout);
usleep( 14345);
printf( "B");
fflush( stdout);
usleep( 13345);
V(semid, 0);
}
wait( NULL);
}
destroy_sem(semid);
return 0;
}
Makefile:
sem:comm.c sem.c
gcc -o $@ $^
.PHONY:cleam
clean:
rm -f sem

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值