2013-11-25 48 views
0

我正在写信号量和分叉(这是必需的,而不是pthreads不幸)的读者/作家的问题的实现。C - 读者/作者(并发):分叉和信号量输出

这是读者的偏好,基本上是一个用户指定读者/写者的数量,并且程序分叉请求的数量。作家选择一个随机数字,将其写入关键部分,并将其报告给控制台。读者只需报告当前的电话号码。

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

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

下面是代码:

#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

对不起,我的意思是我不希望每个进程都在一行中控制关键部分多次迭代而无需关闭。如果我将ITERATION宏增加到10,那么你会看到每个进程连续访问它10次 - 这是无用的。 – user2865485

回答

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