linux信号量进程互斥,Linux下信号量实现进程同步、互斥(生产者消费者问题)

#include /*KEY 为申请信号量的键值,通过键值可以用于不同进程间的通信*/

#define KEY (key_t)14010322

/*仓库大小*/

#define MAX_BUFFER_SIZE10

/*union semun 常用于semctl的最后一个参数,

有的系统上sem.h已包含,可能会因为重复而报错,

如果报错请将其去除。*/

union semun {

int val;

struct semid_ds *buf;

ushort *array;

};

/*仓库,buffer数组用于存贮生产的商品编号(product)

write用于记录生产者生产的下一个商品应存贮在仓库的位置

read用于记录消费者消费的下一个商品在仓库中的位置

很明显这是个循环队列,write、read分别为头尾指针*/

typedef struct _tagShareBuffer{

int buffer[MAX_BUFFER_SIZE];

int writer;

int reader;

}SHAREBUFFER;

static void p(int semid ,int semNum);

static void v(int semid ,int semNum);

int main()

{

int shmid; //共享内存的id

char* shmPtr;

intsemid; //信号量指针

int product = 1; //产品编号,从1开始

SHAREBUFFER* pSharebuffer; //共享内存的指针

int i;

/*申请信号量*/

if ((semid = semget(KEY,3,IPC_CREAT|0660)) == -1)

{

printf("semget error! \n");

return -1;

}

/*三个信号量的初始赋值*/

union semun arg[3];

arg[0].val = 1; //mutex(0)

arg[1].val = MAX_BUFFER_SIZE; //empty(1)

arg[2].val = 0; //full(2)

for(i=0;i<3;i++)

semctl(semid,i,SETVAL,arg[i]);

/*显示三个信号量的初值*/

for(i=0;i<3;i++)

printf("The semval(%d) = %d\n",i,semctl(semid,i,GETVAL,NULL));

/*申请共享内存*/

if ((shmid = shmget(IPC_PRIVATE,sizeof(SHAREBUFFER),0600)) < 0)

{

printf("shmget error!\n");

return -1;

}

if((shmPtr = (char*)shmat(shmid,0,0)) == (void*)-1)

{

printf("shmat error!\n");

return -1;

}

memset((void*)shmPtr,0,sizeof(SHAREBUFFER));

pSharebuffer = (SHAREBUFFER*)shmPtr;

/*创建进程*/

pid_t pid = fork();

if (pid < 0){

printf("creat process error.\n");

return -1;

}

if (pid == 0){

/*子进程,消费者*/

while(1)

{

p(semid ,2);//P(full)

p(semid ,0);//P(mutex)

/*输出三个信号量的值和消费仓库中的产品编号以及位置*/

product = pSharebuffer->buffer[pSharebuffer->reader];

for(i=0;i<3;i++)

printf("son:The semval(%d) = %d\n",i,semctl(semid,i,GETVAL,NULL));

printf("son:release the product from buffer[%d] = %d;\n",pSharebuffer->reader,product);

/* reader++ */

pSharebuffer->reader = (pSharebuffer->reader + 1) % MAX_BUFFER_SIZE;

v(semid ,0);//V(mutex)

v(semid ,1); //V(empty)

sleep(1); //调节消费速度

}

}

else {

//父进程,生产者

while(1)

{

p(semid ,1);//P(empty)

p(semid ,0);//P(mutex)

/*输出三个信号量的值和生产仓库中的产品编号以及位置*/

pSharebuffer->buffer[pSharebuffer->writer] = product;

for(i=0;i<3;i++)

printf("parents:The semval(%d) = %d\n",i,semctl(semid,i,GETVAL,NULL));

printf("parents:Produced the product into buffer[%d] = %d;\n",pSharebuffer->writer,product);

/* 产品编号++ */

product++;

/* write++ */

pSharebuffer->writer = (pSharebuffer->writer + 1) % MAX_BUFFER_SIZE;

v(semid ,0);//V(mutex)

v(semid, 2); //V(full)

sleep(1); //调节生产速度

}

}

return 0;

}

/* p操作 */

void p(int semid ,int semNum){

struct sembuf sb;

sb.sem_num = semNum;

sb.sem_op = -1;

sb.sem_flg = SEM_UNDO;

semop(semid, &sb, 1);

}

/* v操作 */

void v(int semid ,int semNum){

struct sembuf sb;

sb.sem_num = semNum;

sb.sem_op = 1;

sb.sem_flg = SEM_UNDO;

semop(semid, &sb, 1);

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值