【问题标题】:C - Readers/Writers (Concurrency): Forking & Semaphores OutputC - 读取器/写入器(并发):分叉和信号量输出
【发布时间】:2013-12-09 14:49:44
【问题描述】:

我正在编写一个带有信号量和分叉的读者/作家问题的实现(不幸的是,这是必需的,而不是 pthreads)。

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

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

编辑:对不起,如果我问的不是很清楚;下面的输出显示了每个进程(读取器 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

感谢您的帮助!

【问题讨论】:

  • 您的问题/疑问是什么?
  • 对不起,我的意思是我不希望每个进程在不交出它的情况下连续控制临界区多次迭代。如果我将 ITERATION 宏增加到 10,那么您会看到每个进程连续访问它 10 次 - 这是没用的。

标签: c concurrency fork semaphore


【解决方案1】:

对不起,我的意思是我不希望每个进程都控制 临界区连续多次迭代,无需交出。

如果调用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-18
    • 2013-01-16
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多