我正在尝试在C中实现读者和作者问题的变体,变化是作者可以是增量者或减量者,他们应该保持运行计数。下面是我试图实现的代码,我收到错误“Segmentation Fault(core dumped)。我试图调试并从gdb收到这个反馈 - #0 0x0000000000400d84在main()中。 如果有人能够向我解释这个/给我一些如何解决这个错误的提示,我将不胜感激。 谢谢!
#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);
}
答案 0 :(得分:1)
如果rand返回大号,你可能会用完堆栈空间,如@WhozCraig的评论所示
如果你只是在这里指定一些有限值而不是使用rand:
int numReaders = rand();
int numWriters = rand();
我看到它在没有分段错误的情况下运行
答案 1 :(得分:0)
怀疑:pthread_join(readers[i], NULL)
pthread_join的第二个参数应该是var的有效地址,以包含来自现有子线程的返回值的地址。在这种情况下,当子线程退出时,pthread_exit尝试在NULL处写入NULL,我认为这会导致seg错误。尝试将NULL更改为pthread_join中的某个有效地址,以便读取和写入,并查看它是否有效。
编辑:事实证明,POSIX允许将NULL传递给pthread_join(请参阅下面的评论),因此怀疑是无罪释放。