C多线程消费者 - 生产者计划中的分段错误

时间:2014-10-07 19:55:50

标签: c multithreading consumer producer

我目前正在介绍线程程序的概念,并且已经获得了使用线程和信号量模拟股票市场的任务。这是代码:

#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()开始,这就给了我一个分段错误,创建了一个线程...因为它不是我从root创建的代码,所以我&#39 ;我无法回溯错误并修复错误 - 如果有人可以看一下并且可能会给我一些提示,那就太棒了

谢谢!

修改

通过你的帮助解决了问题:)

我在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]);}

由于

1 个答案:

答案 0 :(得分:2)

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

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->slots[stock] = stock_value;