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();
我看到了运行没有分段错误
我正在尝试用 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();
我看到了运行没有分段错误