LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 651|回复: 1

请教一个生产者消费者问题的实现

[复制链接]
发表于 2007-3-3 17:25:23 | 显示全部楼层 |阅读模式
我定义了一个结构体,该结构体内包含三个信号灯

然后将该结构体在父子进程中共享

程序结束时,我释放该结构体结果出现了Segment Fault

请问是什么原因呢?
 楼主| 发表于 2007-3-3 17:26:03 | 显示全部楼层
#define                N        10        /* number of loops */
typedef        int        semaphore;        /* semapthores are a special kind of int */
struct producer_consumer
{
        semaphore        mutex;        /* controls access to critical region */
        semaphore        empty;        /* counts empty buffer slots */
        semaphore        full;        /* counts full buffer slots */
};

void display(char *str)
{
        char *tmp;

        for (tmp = str; *tmp; tmp++)
        {
                write(1, tmp, 1);
                usleep(100);
        }

}

int main(int argc, char *argv[])
{
        int                                 i;
        int                                 shmid;
        struct producer_consumer         *pc;
        struct sembuf                         up = {0, 1, 0};
        struct sembuf                         down = {0, -1, 0};
        int                                pid;

        pc = (struct producer_consumer *)malloc(sizeof(struct producer_consumer));
        if (pc == NULL)
        {
                fprintf(stderr, "unable to malloc memory\n");
                return -1;
        }

        shmid  = shmget(IPC_PRIVATE, sizeof(struct producer_consumer), 0600);
        if (shmid < 0)
        {
                perror("shmget error\n");
                exit(1);
        }

        pc = (struct producer_consumer *)shmat(shmid, 0, 0);
        if ((pc->mutex = semget(IPC_PRIVATE, 1, 0600)) < 0)
        {
                perror("semget mutex error\n");
                exit(1);
        }
        if ((pc->empty = semget(IPC_PRIVATE, 1, 0600)) < 0)
        {
                perror("semget empty error\n");
                exit(1);
        }
        if ((pc->full = semget(IPC_PRIVATE, 1, 0600)) < 0)
        {
                perror("semget full error\n");
                exit(1);
        }

        if (semop(pc->mutex, &up, 1) < 0)
        {
                perror("semop mutex\n");
                exit(1);
        }
        if (semop(pc->empty, &up, 1) < 0)
        {
                perror("semop empty\n");
                exit(1);
        }

        pid = fork();

        if (pid < 0)
        {
                perror("fork");
                exit(-1);
        }

        if (pid > 0)
        {
                /**
                 *         Parent Process
                 */
                for (i=0; i<N; i++)
                {
                        if (semop(pc->empty, &down, 1) < 0)
                        {
                                perror("semop empty\n");
                                exit(1);
                        }
                        if (semop(pc->mutex, &down, 1) < 0)
                        {
                                perror("semop mutex\n");
                                exit(1);
                        }
                        display("ab");
                        if (semop(pc->mutex, &up, 1) < 0)
                        {
                                perror("semop mutex\n");
                                exit(1);
                        }
                        if (semop(pc->full, &up, 1) < 0)
                        {
                                perror("semop full\n");
                                exit(1);
                        }
                }
                wait(NULL);
                if (semctl(pc->mutex, 0, IPC_RMID) < 0)
                {
                        perror("remove mutex\n");
                        exit(1);
                }
                if (semctl(pc->empty, 0, IPC_RMID) < 0)
                {
                        perror("remove empty\n");
                        exit(1);
                }
                if (semctl(pc->full, 0, IPC_RMID) < 0)
                {
                        perror("remove full\n");
                        exit(1);
                }
                if (shmdt((void*)pc) < 0)
                {
                        perror("unable to detach shared variable\n");
                        exit(1);
                }
                if (shmctl(shmid, IPC_RMID, 0) < 0)
                {
                        perror("unable to destroy shared variable\n");
                        exit(1);
                }
//                free(pc);
        }
        else
        {
                /**
                 *         Child Process
                 */
                for (i=0; i<N; i++)
                {
                        if (semop(pc->full, &down, 1) < 0)
                        {
                                perror("semop full\n");
                                exit(1);
                        }
                        if (semop(pc->mutex, &down, 1) < 0)
                        {
                                perror("semop mutex\n");
                                exit(1);
                        }
                        display("cd\n");
                        if (semop(pc->mutex, &up, 1) < 0)
                        {
                                perror("semop mutex\n");
                                exit(1);
                        }
                        if (semop(pc->empty, &up, 1) < 0)
                        {
                                perror("semop empty\n");
                                exit(1);
                        }
                }
                if (shmdt((void*)pc) < 0)
                {
                        perror("unable to detach shared variable\n");
                        exit(1);
                }
        }

        return 0;
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表