【问题标题】:Producer, consumer POSIX生产者、消费者 POSIX
【发布时间】:2015-05-07 23:21:45
【问题描述】:

我正在尝试使用 C POSIX 信号量编写简单的生产者消费者应用程序。 消费者:

int memoryID;
struct wrapper *memory;

int main(int argc, char **argv) {

    srand(time(NULL));
    key_t sharedMemoryKey = ftok(".",MEMORY_KEY);
    if(sharedMemoryKey==-1)
    {
        perror("ftok():");
        exit(1);
    }

    memoryID=shmget(sharedMemoryKey,sizeof(struct wrapper),0);

    if(memoryID==-1)
    {
        perror("shmget(): ");
        exit(1);
    }

    memory = shmat(memoryID,NULL,0);
    if(memory== (void*)-1)
    {
        perror("shmat():");
        exit(1);
    }

    while(1)
    {
        int r = rand();
        sem_wait(&memory->full);
        sem_wait(&memory->mutex);
        int n;
        sem_getvalue(&memory->full,&n);
        printf("Removed item: %d",(memory->array)[n]);
        usleep(1000000);
        sem_post(&memory->mutex);
        sem_post(&memory->empty);
    }

}

制作人:

int memoryID;
struct wrapper *memory;
int rc;

void atexit_function() {
    rc = shmctl(memoryID, IPC_RMID, NULL);
    rc = shmdt(memory);
}

int main(int argc, char **argv) {
    atexit(atexit_function);
    //creating key for shared memory
    srand(time(NULL));
    key_t sharedMemoryKey = ftok(".", MEMORY_KEY);
    if (sharedMemoryKey == -1) {
        perror("ftok():");
        exit(1);
    }

    memoryID = shmget(sharedMemoryKey, sizeof(struct wrapper), IPC_CREAT | 0600);
    if (memoryID == -1) {
        perror("shmget():");
        exit(1);
    }

    memory = shmat(memoryID, NULL, 0);
    if (memory == (void *) -1) {
        perror("shmat():");
        exit(1);
    }

    //initialization
    memset(&memory->array, 0, sizeof(memory->array));
    sem_init(&memory->mutex, 1, 1);
    sem_init(&memory->empty, 1, SIZE_OF_ARRAY);
    sem_init(&memory->full, 1, 0);

    if (memoryID == -1) {
        perror("shmget(): ");
        exit(1);
    }

    while(1)
    {
        int r = rand();
        sem_wait(&memory->empty);
        sem_wait(&memory->mutex);
        int n;
        sem_getvalue(&memory->full,&n);
        printf("Adding task\t Value:%d\tNumber of tasks waiting:%d \n",r,n);
        (memory->array)[n]=r;
        usleep(1000000);
        sem_post(&memory->mutex);
        sem_post(&memory->full);
    }

}

common.h:

#define MEMORY_KEY 5
#define SIZE_OF_ARRAY 10

struct wrapper
{
    int array[SIZE_OF_ARRAY];
    sem_t empty;
    sem_t mutex;
    sem_t full;
};

发生了什么:

Producer 启动成功

Producer 正在成功添加元素到 table 并在启动 producer 后快速打印出来,

我开始消费者消费者不从 数组甚至一次

生产者填满数组并等待

我真的不明白问题出在哪里。我怀疑问题是实现而不是算法,因为算法取自维基百科Link

【问题讨论】:

  • 您可能希望在strace 工具下运行您的程序,这是一个很好的调试辅助工具,因此您可以看到程序在做什么。此外,为确保您不会被缓冲所迷惑,请在您的消费者 printf() 语句中插入换行符,或在调用 printf 后调用 fflush(stdout)。
  • 两个源文件中似乎缺少几个#include 语句。
  • 您应该在 common.h 文件中添加标准(不要多次包含我)包装器:#ifndef COMMON_H #define COMMON_H ..... #endif // COMMON_H
  • 参数 'argc' 和 'argv[]' 没有被使用,因此编译器会针对每个参数发出警告。建议使用'int main(void)'

标签: c concurrency posix ipc


【解决方案1】:

您的消费者工作正常。它只是没有刷新到标准输出。通过在您的消费者printf 呼叫结束时添加\n 来执行建议。您也可以通过等待更长的时间来查看它的工作原理。您的生产者将在消费者执行几次迭代后再次开始生产。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多