【问题标题】:Segmentation fault in C multithreaded consumer-producer programC 多线程消费者-生产者程序中的分段错误
【发布时间】:2014-12-02 08:41:05
【问题描述】:

我目前正在了解线程程序的概念,并被分配使用线程和信号量来模拟股票市场。代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <pthread.h>

#define NUM_WRITERS 5   
#define NUM_READERS 5   
#define STOCKLIST_SIZE 10  

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 
sem_t stop_writers;

typedef struct
{   int readers;
    int slots[STOCKLIST_SIZE];
} mem_structure;

int id[NUM_READERS + NUM_WRITERS];
mem_structure *stocklist;
pthread_t thr[NUM_WRITERS + NUM_READERS];

void init(){
    sem_init(&stop_writers, 0, 1);
}

void cleanup(int signo) // clean up resources by pressing Ctrl-C
{   sem_destroy(&stop_writers);
    printf("Closing...\n");
    exit(0);
}


void write_stock(int n_writer)
{
    int stock = (int)(rand()%STOCKLIST_SIZE);
    int stock_value = 1 + (int)(100.0 * rand()/(RAND_MAX + 1.0));
    stocklist->slots[stock] = stock_value;
    fprintf(stderr, "Stock %d updated by BROKER %d to %d\n", stock, n_writer, stock_value);
}

void* writer(void* id){
    int my_id = *((int*) id);
    int i = my_id;

    while (1)
    {
        pthread_mutex_lock(&mutex);
        sem_wait(&stop_writers);
        write_stock(i);
        pthread_mutex_unlock(&mutex);
        sem_post(&stop_writers);

        sleep(1);
        ++i;
    }

}

void read_stock(int pos, int n_reader){
    fprintf(stderr, "Stock %d read by client %d = %d.\n", pos, n_reader, stocklist->slots[pos]);
}

void* reader(void* id){
    int my_id = *((int*) id);
    int i = my_id;

    while (1)
    {   sem_wait(&stop_writers);
        read_stock((int)(rand()%STOCKLIST_SIZE), i);
        sem_post(&stop_writers);
        sleep(1 + (int) (3.0 * rand() / (RAND_MAX + 1.0)));
        ++i;
    }
}

void monitor() // main process monitors the reception of Ctrl-C
{
    struct sigaction act; 
    act.sa_handler = cleanup; 
    act.sa_flags = 0; 
    if ((sigemptyset(&act.sa_mask) == -1) || 
        (sigaction(SIGINT, &act, NULL) == -1)) 
        perror("Failed to set SIGINT to handle Ctrl-C");
    while(1){
        sleep(5);
        printf("Still working...\n");
        }
    exit(0);
    }


int main(void)
{   int i, j;
    init();

    for (i = 0; i < NUM_WRITERS; ++i){
        id[i] = i;
        pthread_create(&thr[i], NULL, writer, &id[i]);}
    for (j = i; j < NUM_READERS; ++j){
        id[j] = j;
        pthread_create(&thr[j], NULL, reader, &id[j]);}

    stocklist->readers = 0;
pthread_exit(NULL);

    monitor();
    return 0;
}

这几乎在 main() 开始时就给了我一个分段错误,并创建了一个线程......因为它不是我从根目录创建的代码,所以我无法回溯错误并且修复它 - 如果有人可以看一下并给我一些提示,那就太好了

谢谢!

编辑

已解决问题,感谢您的帮助 :)

我在 init() 上初始化了 stocklist,

void init(){
    sem_init(&stop_writers, 0, 1);
    stocklist = (mem_structure*)malloc(sizeof(mem_structure));
}

并更改了main()中的第二个cicle,

for (j = i; j < NUM_READERS+NUM_WRITERS; ++j){
    id[j] = j;
    pthread_create(&thr[j], NULL, reader, &id[j]);}

谢谢

【问题讨论】:

  • 另一个提示:恢复为空 main() 并添加回代码,直到找到哪个产生错误。
  • 还有一个提示 - gdb 等调试器可以准确地告诉您发生分段错误的位置。只需使用 -g 标志编译程序,然后从 gdb 运行运行可执行文件。
  • stocklist 似乎从未被初始化,这会导致问题。
  • stocklist 是一个指向结构的指针,但从未分配过内存。 READERS 的线程永远不会被创建,因为j 将从 5 开始,NUM_READERS 是 5。
  • @Cryo 这是主要问题,是的 - 我只是不确定如何正确初始化它。我最终在 init() 函数中对其进行了初始化,并且成功了,谢谢!

标签: c multithreading consumer producer


【解决方案1】:

这是我为追查问题所做的:

gcc -g program.c -lpthread

gdb a.out

run

输出:

Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb7feeb70 (LWP 23060)] 0x08048834 in write_stock (n_writer=0) at program.c:44 44 stocklist->slots[stock] = stock_value;

看来问题出在这里:

stocklist-&gt;slots[stock] = stock_value;

【讨论】:

  • 没错 - 原来主要错误是 stocklist 没有初始化,所以无论如何都无法访问它
猜你喜欢
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 2018-09-24
  • 2017-03-10
  • 2017-02-01
相关资源
最近更新 更多