C 段错误 - 读者和作者

C Segmentation Fault - readers and writers

我正在尝试用 C 实现读者和作者问题的一个变体,这个变体是作者可以是递增者或递减者,他们应该保持 运行 计数。下面是我试图实现的代码,我收到错误“Segmentation Fault (core dumped)”。我尝试调试并从 gdb 收到此反馈 - #0 0x0000000000400d84 in main ()。 如果有人能够向 me/give 我解释如何修复此错误,我将不胜感激。 谢谢!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

#define WAIT 20
#define NEW 0

#define DECREMENT 0
#define INCREMENT 1

#define TIME 5
#define VALUE 1
#define COMMON 0


int readerCount = NEW;
int total = 0;
int v;
sem_t mutex;
sem_t access_data;



int increment_or_decrement() {
    int d;
    return d = rand() % 2;
}

void *writer(void *arg) {
    int version = increment_or_decrement();

    int *iID = (int *) arg;
    int *dID = (int *) arg;

    sleep(rand() % WAIT);

    sem_wait(&access_data);

    if (version == INCREMENT) {
        fprintf(stderr, "Incrementer %d accessed the data\n", *iID);
        total++;
        fprintf(stderr, "Total: %d\n", total);
    }
    else {
        fprintf(stderr, "Decrementer %d accessed the data\n", *dID);
        total--;
        fprintf(stderr, "Total: %d\n", total);
    }

    sleep(TIME);

    sem_post(&access_data);

    pthread_exit(NULL);

}


void *reader(void *arg) {
    int *id = (int *) arg;

    sleep(rand() % WAIT);

    while(1) {
        if (readerCount == NEW) {
            sem_wait(&mutex);

            v = version;
            readerCount++;

            if (readerCount == 1)
                sem_wait(&access_data);

            sem_post(&mutex);

            fprintf(stderr, "Reader %d accessed the data\n", *id);

            sem_wait(&mutex);

            readerCount--;

            if(readerCount == NEW)
                sem_post(&access_data);

            sem_post(&mutex);

            pthread_exit(NULL);
        }
    }

}


int main() {
    int numReaders = rand();
    int numWriters = rand();
    int i;

    sem_init(&mutex, COMMON, VALUE);
    sem_init(&access_data, COMMON, VALUE);

    pthread_t readers[numReaders];
    pthread_t writers[numWriters];

    int readerID[numReaders];
    int writerID[numWriters];

    for (i = 0; i < numReaders; i++)
        readerID[i] = i;

    for (i = 0; i < numWriters; i++)
        writerID[i] = i;

    for (i = 0; i < numReaders; i++) {
        if(pthread_create(&readers[i], NULL, reader, (void *) &readerID[i]) != 0) {
            printf("Child failed\n");
            exit(EXIT_FAILURE);
        }
    }

    for (i = 0; i < numWriters; i++) {
        if (pthread_create(&writers[i], NULL, writer, (void *) &writerID[i]) != 0) {
            printf("Child failed\n");
            exit(EXIT_FAILURE);
        }
    }

    for (i = 0; i < numReaders; i++) {
        if (pthread_join(readers[i], NULL) != 0) {
            printf("Join failed\n");
            exit(EXIT_FAILURE);
        }
    }

    for (i = 0; i < numWriters; i++) {
        if (pthread_join(writers[i], NULL) != 0) {
            printf("Join failed\n");
            exit(EXIT_FAILURE);
        }
    }

    sem_destroy(&access_data);
    sem_destroy(&mutex);
}

嫌疑人:pthread_join(readers[i], NULL)

pthread_join 的第二个参数应该是 var 的有效地址,以包含来自现有子线程的 return 值的地址。在这种情况下,当子线程退出时,pthread_exit 尝试在 NULL 处写入 NULL,我认为这会导致段错误。尝试为读取器和写入器将 NULL 更改为 pthread_join 中的某个有效地址,看看它是否有效。

编辑:事实证明 POSIX 允许将 NULL 传递给 pthread_join(见下面的评论),因此嫌疑人被宣告无罪。

如果@WhozCraig

评论中指出 returns 大数字,您可能 运行 出栈 space

如果你只是分配一些有限的值而不是在这里使用 rand:

  int numReaders = rand();
  int numWriters = rand();

我看到了运行没有分段错误