linux进程间通讯实例二

在Linux下或者Windows下实现读者写者问题。

写者优先
5个读者,3个写者
如果读者来:
1) 无读者、写者,新读者可以读;
2) 无写者等待,但有其他读者正在读,新读者可以读;
3) 有写者等待,但有其他读者正在读,新读者等;
4) 有写者写,新读者等
如果写者来:
1) 无读者,新写者可以写;
2) 有读者,新写者等待;

3) 有其他写者或等待,新写者等待


题中的要点:

1、多个读者可以同时进行读操作

2、如果有人在写,别人则不能读也不能写

3、读、写者来则排在队列末端。不能让读者插队

综上,读写者之间有互斥,写着与写着之间互斥。两层关系

int main()
{
    int id_this;
    int shm1;
    int shm2;
    int shm3;
    shm1=shmget(1,8,IPC_CREAT|0777);
    shm2=shmget(2,8,IPC_CREAT|0777);
    shm3=shmget(3,8,IPC_CREAT|0777);
    int *cnt=(int *)shmat(shm1,0,0);
    int *buf=(int *)shmat(shm2,0,0);
    int *idt=(int *)shmat(shm3,0,0);
    *idt=1;
    int n;
    int mutex_rw;
    int mutex_rr;
    int mutex_ww;
    int mutex;
    sem_init();
    sem_crea(mutex_rr,1);
    sem_crea(mutex_rw,1);
    sem_crea(mutex_ww,1);
    sem_crea(mutex,1);
    *cnt=0;
    *buf=0;
    int _time;
//每调用一次fork,程序就会由1个变为两个,如果调用两次fork实际上会生成四个进程(类似于一棵树的结构)我们需要创建2的3次方:8个进程。
    pid_t p[3];
    for(int i=0;i<3;i++)
        p[i]=fork();

    if(p[0]==0||p[0]!=0&&p[1]==0&&p[2]==0) 
    {
        sleep(1);
        printf("proccess reader has been built\n");
        while(1)
        {
        srand((int)time(0));
        _time=rand()%3+1;
        sleep(_time);
        p1(mutex_rw);   //防止读者插队的锁
        p1(mutex_rr);
        int n=*cnt;
        n++;
        *cnt=n;
        if(n==1)p1(mutex); //第一个读者把数据区加锁。
        v(mutex_rr);
        v(mutex_rw);

        printf("reader %d\n",*buf);

        p1(mutex_rr);
        n=*cnt;
        n--;
        *cnt=n;

        if(n==0)v(mutex);//最后一个读者把锁解开

        v(mutex_rr);
        }
    }
    else if(p[0]!=0)
    {
        sleep(1);
        printf("process writer has been built\n");
        while(1)
        {
        srand((int)time(0));
        _time=rand()%3+1;
        sleep(_time);
        p1(mutex_rw);
        p1(mutex);
        int n=*buf;
        n++;
        printf("write %d into buf\n",n);
        *buf=n;
        v(mutex);
        v(mutex_rw);
        }
    }
}

具体的头文件、函数的写法请参考(这个实例中因为有BUG我把P改成了p1)

Linux信号量之生产者与消费者(1)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值