C - 读者/作者(并发):分叉&信号量输出

时间:2013-11-25 01:43:28

标签: c concurrency fork semaphore

我正在编写Reader / Writer的信号量和分叉问题的实现(这是必需的,而不是遗憾的是pthreads)。

这是读者的偏好,基本上是用户指定读者/作者的数量,程序会分离所请求的每个读者/作者的数量。作家选择一个随机数,将其写入临界区,然后将其报告给控制台。读者只需报告当前的数字。

我正在使用信号量来管理它,并且由于某种原因,一旦一个进程得到关键部分,它就会迭代所有预定数量的循环,然后允许下一个进程访问它。我觉得它可能与我的fork() - main中的循环有关,虽然我不确定。

编辑:对不起,如果我问的问题不完全清楚;下面的输出显示每个进程(读取器1,写入器1等)每次连续两次访问临界区(如果我将ITERATION增加到10,则为10x),这不是我想要的。它应该有一个更随机的出现输出(每个进程访问它一次然后将其关闭)。我不知道为什么每个进程都能像现在一样阻止访问。

以下是代码:

#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include "asm/unistd.h"

#include <semaphore.h>

#define ITERATION 2

int *readCount, *crit_sec;
sem_t wrt, mutex, *s1, *s2;

void writer (int numWriter) {
    sem_wait(&wrt);
    *crit_sec = rand() % 100 + 1;
    printf("Writer %d - Wrote: %d\n", numWriter, *crit_sec);
    sem_post(&wrt);

    return;
}

void reader (int numReader) {
    sem_wait(&mutex);
    *readCount++;
    if (*readCount == 1) sem_wait(&wrt);
    sem_post(&mutex);
    printf("Reader %d - Read: %d\n", numReader, *crit_sec);
    sem_wait(&mutex);
    *readCount--;
    if (*readCount==0) sem_post(&wrt);
    sem_post(&mutex);

    return;
}

int main (int argv, char **argc) {
    int numRead, numWrite;
    void *ptr1 = mmap(NULL, 2*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
    void *ptr2 = mmap(NULL, 2*sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
    crit_sec=ptr1, readCount=ptr1+1;
    *crit_sec=0, *readCount=0;

    s1=ptr2, s2=ptr2+1;
    *s1=mutex, *s2=wrt;
    sem_init(&mutex,1,1);
    sem_init(&wrt,1,1);

    if (argv !=3) {
            printf("Incorrect usage - must use: ./ReadersWriters [# readers] [# writers]\n");
            return 0;
    }

    if (sscanf (argc[1], "%i", &numRead)!=1|| sscanf (argc[2], "%i", &numWrite)!=1) {
            printf("Incorrect usage - must use: ./ReadersWriters [# readers] [# writers]\n");
            return 0;
    }

    int rcnt = 0;
    while (rcnt++ < numRead) {
            if (fork()==0) {
                    int i=0;        
                    for(;i<ITERATION;i++) reader(rcnt);
                    return;
            }
    } 

    int wcnt = 0;
    while (wcnt++ < numWrite) {
            if (fork()==0) {
                    int j=0;
                    for (;j<ITERATION;j++) writer(wcnt);
                    return;  
            }
    }

    return 0;
}

这是一个示例输出(尽管流程顺序可能不同):

Reader 1 - Read: 0
Reader 1 - Read: 0
Writer 1 - Wrote: 84
Writer 1 - Wrote: 87
Reader 2 - Read: 87
Reader 2 - Read: 87
Writer 2 - Wrote: 84   
Writer 2 - Wrote: 87

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

  

对不起,我的意思是我不希望每个进程控制   关键部分连续多次迭代而不将其关闭。

如果调用e,调度程序没有义务切换到另一个线程。 G。 sem_post(),尤其是标准时间安排政策SCHED_OTHER(请参阅man sched_setscheduler)。也就是说,有#define ITERATION 5我有时会得到e。 G:

Reader 1 - Read: 0
Reader 2 - Read: 0
Reader 1 - Read: 0
Reader 1 - Read: 0
Reader 1 - Read: 0
Reader 2 - Read: 0
Reader 1 - Read: 0
Reader 2 - Read: 0
Reader 2 - Read: 84
Reader 2 - Read: 84
Writer 1 - Wrote: 84
Writer 1 - Wrote: 87
Writer 2 - Wrote: 84
Writer 2 - Wrote: 87
Writer 2 - Wrote: 78
Writer 1 - Wrote: 78
Writer 2 - Wrote: 16
Writer 1 - Wrote: 16
Writer 2 - Wrote: 94
Writer 1 - Wrote: 94