用信号量同步生产者消费者的问题

elated 2010-01-05 11:09:51
用信号量同步生产者消费者。
大家帮我看看这个程序错在哪了。
为什么信号量为0时没有阻塞进程?

还有sembuf结构有个sem_flag成员, 那个SEM_UNDO位是做什么的?我看apue没看明白。


#include "apue.h"
#include <assert.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/wait.h>

#define N 10
#define MUTEX 0
#define FULL 1
#define EMPTY 2

typedef union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};

int num = 0;

int init_sem(int, int , int);
int up(int, int);
int down(int, int);
void producer(int);
void consumer(int);

int main (int argc, char *argv[])
{
int semid;
pid_t pid1, pid2;

if ((semid = semget(IPC_PRIVATE, 3, 0660)) < 0)
err_sys("semget error");

init_sem(semid, MUTEX, 1); /* mutex */
init_sem(semid, FULL, 0); /* full */
init_sem(semid, EMPTY, N); /* empty */

if ((pid1 = fork()) < 0 ) {
err_sys("fork error");
} else if( pid1 == 0) {
producer(semid); /* child1 producer */
} else {
if((pid2 = fork()) < 0 ){
err_sys("fork error");
} else if ( pid2 == 0) { /* child2 consumer */
consumer(semid);
} else {
if (waitpid(pid1, NULL, 0) != pid1 ||
waitpid(pid2, NULL, 0 ) != pid2)
err_sys("waitpid error");
}
}

if (semctl(semid, 0, IPC_RMID) < 0)
err_sys("semctl error");

exit(0);
}

int init_sem(int semid, int semnum, int val)
{
union semun unarg;

unarg.val = val;
if (semctl(semid, semnum, SETVAL, unarg) < 0)
err_sys("semctl error");
return 0;
}

int up(int semid, int semnum)
{
struct sembuf semoparray[1];

semoparray[0].sem_num = semnum;
semoparray[0].sem_op = 1;
semoparray[0].sem_flg = 0;

if (semop(semid, semoparray, 1) < 0)
err_sys("semop error");

return 0;
}

int down(int semid, int semnum)
{
struct sembuf semoparray[1];

semoparray[0].sem_num = semnum;
semoparray[0].sem_op = -1;
semoparray[0].sem_flg = 0; /* IPC_NOWAIT, SEM_UNDO(这个宏有什么作用?) */

if (semop(semid, semoparray, 1) < 0)
err_sys("semop error");

return 0;
}

void producer(int semid)
{
int i = 1000;
int sem1, sem2;
while (i--) {
assert((sem1 = semctl(semid, EMPTY, GETVAL, NULL))<= 10);
assert((sem2 = semctl(semid, FULL, GETVAL, NULL)) >= 0);
down(semid, EMPTY);
down(semid, MUTEX);
num++;
printf("producer num = %i \n", num);
printf("EMPTY = %i ; FULL = %i ; \n", sem1, sem2);
up(semid, MUTEX);
up(semid, FULL);
}

exit(0);
}

void consumer(int semid)
{
int i = 1000;
int sem1, sem2;
while (i--) {
assert((sem1 = semctl(semid, EMPTY, GETVAL, NULL))<= 10);
assert((sem2 = semctl(semid, FULL, GETVAL, NULL)) >= 0);
down(semid, FULL);
down(semid, MUTEX);
num--;
printf("consumer num = %i \n", num);
printf("EMPTY = %i ; FULL = %i ; \n", sem1, sem2);
up(semid, MUTEX);
up(semid, MUTEX);
up(semid, EMPTY);
}

exit(0);
}


...全文
259 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
goooglemister 2010-01-13
  • 打赏
  • 举报
回复
up
elated 2010-01-13
  • 打赏
  • 举报
回复
up
elated 2010-01-08
  • 打赏
  • 举报
回复
多写了个up(semid, MUTEX);
elated 2010-01-08
  • 打赏
  • 举报
回复
up
xsz19880101 2010-01-08
  • 打赏
  • 举报
回复
#include"apue.h" 与#include<stdio.h> 的区别。
查找头文件的路径不一样,一个是本地,一个是系统标准头文件路径 ,也就是先从当前目录搜索指定文件,如果没有,再从系统标准路径搜索.

程序中最后多写了个up(semid, MUTEX);


steptodream 2010-01-06
  • 打赏
  • 举报
回复
不会 帮顶

23,114

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧