信号转化java_一个包含了信号、信号量、共享内存的例子(转)

#include

#include

#include

#include

#include

#include

#define SHMKEY1 (key_t)0x10

#define SHMKEY2 (key_t)0x15

#define SEMKEY  (key_t)0x20

#define SIZ 5*BUFSIZ

#define IFLAGS (IPC_CREAT|IPC_EXCL)

#define ERR ((struct databuf*)-1)

//p1,v1是针对第一个信号进行的操作

struct sembuf p1 = {0, -1, 0};

struct sembuf v1 = {0, 1, 0};

//p2,v1是针对第二个信号进行的操作

struct sembuf p2 = {1, -1, 0};

struct sembuf v2 = {1, 1, 0};

//表示两个内存共享区和一个信号量集合

static int shmid1, shmid2, semid;

//作为暂时存放数据的结构体

struct databuf

{

int d_nread;

char d_buf[SIZ];

};

void fatal(char *mes)

{

perror(mes);

exit (1);

}

/**创建两个共享内存,并且分别shmat给两个参数*/

void getshm (struct databuf **p1, struct databuf **p2)

{      //创建共享内存

if ((shmid1=shmget(SHMKEY1, sizeof(struct databuf), 0600|IFLAGS)) < 0)

{

fatal ("shmget");

}

if ((shmid2=shmget(SHMKEY2, sizeof(struct databuf), 0600|IFLAGS)) < 0)

{

fatal ("shmget");

}

//映射

if ((*p1=(struct databuf*)(shmat(shmid1, 0, 0))) == ERR)

{

fatal("shmat");

}

if((*p2=(struct databuf*)(shmat(shmid2, 0, 0))) == ERR)

{

fatal("shmat");

}

}

int getsem()

{

//获取一个长度为2的信号量集合;

if ((semid=semget(SEMKEY, 2, 0600|IFLAGS)) < 0)

{

fatal("segmet");

}

//初始化信号量,假定第一个信号灯没有资源

if (semctl(semid, 0, SETVAL, 0) < 0)

{

fatal ("semctl");

}

//第二个有信息,如果两个信号都没有资源,将会出现死锁

//书上该处有问题

if (semctl(semid, 1, SETVAL, 1) < 0)

{

fatal ("semctl");

}

return (semid);

}

//回收共享两个内存区和一个信号量集合

void myremove()

{

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

{

fatal("shmctl");

}

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

{

fatal("shmctl");

}

if (semctl(semid, 0, IPC_RMID, NULL) < 0)

fatal("semctl");

exit(0);

}

void reader(int semid, struct databuf *buf1, struct databuf *buf2)

{

for(;;)

{

unsigned short val= semctl(semid,0,GETVAL,null);

if(val<=0)

{

semop(semid,&v1,1);

}

else{

//申请第一个信号灯资源

semop(semid, &p1, 1)

}

//从键盘读入数据,放在buf1->d_buf,

//read第一个参数是文件描述符,其中0表示从终端输入:如键盘

buf1->d_nread = read(0, buf1->d_buf, SIZ);

//v操作,释放第一个信号灯资源

semop(semid, &v1, 1);

//p操作,申请第二个信号灯资源,若没有资源,则阻塞进程直到有资源.

semop(semid, &p2, 1);

buf2->d_nread = read(0, buf2->d_buf, SIZ);

//v操作,释放第二个信号灯资源

semop(semid, &v2, 1);

}

}

void writer(int semid, struct databuf *buf1, struct databuf *buf2)

{

for(;;)

{

//p操作,等待第一个信号的资源

semop(semid, &p1, 1);

//1代表输出到屏幕

write(1, buf1->d_buf, buf1->d_nread);

//释放第一个信号灯资源

semop(semid, &v1, 1);

//p操作,申请第二个信号灯资源,若没有资源,则阻塞进程直到有资源.

semop(semid, &p2, 1);

write(1, buf2->d_buf, buf2->d_nread);

semop(semid, &v2, 1);

}

}

int main()

{

int semid, pid;

struct databuf *buf1, *buf2;

semid = getsem();

getshm (&buf1, &buf2);

switch(pid=fork())

{

case -1:

fatal("fork");

break;

case 0:

writer(semid, buf1, buf2);

break;

default:

//在主进程中把中断程序的ctrl+c和myremove函数建立联系,

//来回收系统资源:共享内存区,信号量.

signal (SIGINT, myremove);

reader(semid, buf1, buf2);

break;

}

exit(0);

}

posted on 2009-10-08 11:19 月光记忆 阅读(1447) 评论(0)  编辑  收藏 所属分类: c进程间通信

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值