免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1538 | 回复: 0
打印 上一主题 下一主题

两个独立程序producer和consumer使用system v信号量,打开存在信号量失败?(付源码) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-03-21 17:22 |只看该作者 |倒序浏览
#include <stdio.h>
#include <errno.h>
#include <signal.h>

#ifdef __linux
#include <linux/sem.h>
#include <sys/types.h>
#include <fcntl.h>
#include <linux/wait.h>
#else
#include <windows.h>
#endif

#define SEM_LOCK "./lock2"
#define SEM_FULL "./full2"
#define SEM_EMPTY "./empty2"

#ifdef WIN32
int myflag = 0;
#else
int myflag = IPC_CREAT|IPC_EXCL|000666;
#endif

int init(char *pathname,  int value, int flag);
void setvalue(int sem_id, int value);
void mywait(int sem_id);
void release(int sem_id);
void destroy(int sem_id);

int g_lock;
int g_full;
int g_empty;


void producer();
void consumer();

int main(int argc, char **agrv)
{
        int childpid1 = 0;
        int childpid2 = 0;
        int stat = 0;
        g_lock = init(SEM_LOCK, 1, myflag);
        g_full = init(SEM_FULL, 0, myflag);
        g_empty = init(SEM_EMPTY, 2, myflag);


       
        if ((g_lock < 0) || (g_full < 0) || (g_empty < 0))
                perror("init error");


        if ((childpid1 = fork()) == 0)
        {
//                consumer();     
                producer();
                exit(0);
        }
       
        printf("wait all child\n");

        waitpid(-1, 0, 0);


       
        printf("destroy sem\n");
        destroy(g_lock);
        destroy(g_full);
        destroy(g_empty);

        printf("end main\n");
       
        return 0;
}

void mywait(int sem_id)
{
#ifdef __linux
        struct sembuf buf;
        buf.sem_num = 0;
        buf.sem_op = -1;
        buf.sem_flg = SEM_UNDO;
        semop(sem_id, &buf, 1);
#endif
}

void release(int sem_id)
{
#ifdef __linux
        struct sembuf buf;
        buf.sem_num = 0;
        buf.sem_op = 1;
        buf.sem_flg = SEM_UNDO;
        semop(sem_id, &buf, 1);
#endif       
}

void setvalue(int sem_id, int value)
{
#ifdef __linux
        union semun arg;
        arg.val = value;
        semctl(sem_id, 0 , SETVAL, arg);
#endif
}

void destroy(int sem_id)
{
#ifdef __linux
        semctl(sem_id, 0, IPC_RMID);
#endif
}

int init(char *pathname,  int value, int flag)
{
#ifdef __linux
        union semun arg;
        struct semid_ds sem_info;
        int sem_id = 0;
        int init_ok = 0;
        key_t key = ftok(pathname, 'l');
        if (key < 0)
        {
                printf("init()----failure :%s\n", strerror(errno));
        }

        printf("init()---- key = %d\n", key);
       
        sem_id = semget(key, 1, flag);
       
        if (sem_id >0)
        {
                setvalue(sem_id, value);
                printf("init() ----- pathname = %s, semid = %d\n", pathname, sem_id);
                return sem_id;
        }
        else if (sem_id <=0)
        {
                int tmp_errno = errno;
                if (tmp_errno == EEXIST)
                {
                        sem_id == semget(key, 1, IPC_CREAT | 00666);
                        if (sem_id < 0)
                        {
                                tmp_errno = errno;
                                printf("init() ----- open semampore : semid = %d, %s\n",
                                        sem_id, strerror(tmp_errno));
                                return sem_id;
                        }
                        arg.buf = &sem_info;

                        if ((semctl(sem_id, 0, IPC_STAT, arg)) == -1)
                        {
                                printf("init() ----- get status  :pathname = %s, semid = %d, %s\n",
                                        pathname, sem_id, strerror(errno));
                                return -1;
                        }
                        else
                        {
                                if (arg.buf->sem_otime == 0)
                                        setvalue(sem_id, value);

                                printf("init() ----- , setvalue :pathname = %s, semid = %d, %s\n",
                                        pathname, sem_id, strerror(errno));
                                return sem_id;
                        }                       
                }
                else
                {
                        printf("init() ----- other error :pathname = %s, semid = %d, %s\n",
                                pathname, sem_id, strerror(tmp_errno));
                }
        }

#endif
        return -1;
}

void producer()
{
        int i=0;
        for (i=0; i<10; i++)
        {
                mywait(g_empty);
                mywait(g_lock);
                printf("process  = %d, produce()---- i = %d\n", getpid(), i);
                release(g_lock);
                release(g_full);

#ifdef WIN32
                Sleep(1000);
#else
                sleep(1);
#endif
        }
}

void consumer()
{
        int i=0;
        for (i=0; i<10; i++)
        {
                mywait(g_full);
                mywait(g_lock);
                printf("process  = %d, consumer()---- i = %d\n", getpid(), i);
                release(g_lock);
                release(g_empty);

#ifdef WIN32
                Sleep(1000);
#else
                sleep(1);
#endif
        }
}



//出错代码段,sem_id = -1, strerror(tmp_errno)) 为files exist,如何得到确的sem_id,环境fedora6
                        sem_id == semget(key, 1, IPC_CREAT | 00666);
                        if (sem_id < 0)
                        {
                                tmp_errno = errno;
                                printf("init() ----- open semampore : semid = %d, %s\n",
                                        sem_id, strerror(tmp_errno));
                                return sem_id;
                        }



        if ((childpid1 = fork()) == 0)
        {
//                consumer();     
                producer(); //如果是consumer使用上面那行
                exit(0);
        }

[ 本帖最后由 lxrlxr2002 于 2008-3-21 17:26 编辑 ]

test_systemv_producer.rar

18.31 KB, 下载次数: 21

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

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP