使用指向main

时间:2018-08-01 19:57:03

标签: c++ pthreads

我是pthread的新手,它试图实现生产者/消费者问题,该问题将使用户选择缓冲区大小,生产者数量,消费者数量和项目总数。我一直在浏览我认为栈溢出时类似的东西,但似乎无法正确解决问题。

我的代码有一个主类,它产生了生产者和消费者。它向生产者和消费者提供指向main中初始化的栈的指针(或者至少我正在尝试)。我以为自己在做的事情是合法的,在CLion中我得到了我想要的预想性文本选项,所以我以为我可以正确地链接它,但是当我尝试阅读顶级元素时却遇到了麻烦。

我使用GDB来确保知道崩溃所在的行,但是不了解我的设置有什么问题。在调试时,我确认生产者首先要通过其push()命令,但是使用方在尝试top()或pop()时失败。我在这里看到了一些OP出现问题的线程,因为他们没有加入他们的线程,但是我很茫然。

#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stack>
#include <cstring>
#include <semaphore.h>
#include <pthread.h>
#define N 10000

sem_t mutex;
sem_t fullCount;
sem_t emptyCount;
int iCount = 0;

typedef struct _thread_data{
    int id;
    int itemcount;
    std::stack<char>* ptr;
}thread_data;

void *producer(void *arg){
    std::cout << "spawned producer\n";
    thread_data *data = (thread_data *)arg;
    while(true){
        char message = 'X';
        sem_wait(&emptyCount);
        sem_wait(&mutex);
        if(iCount < data->itemcount){
            data->ptr->push(message);
            iCount++;
            char temp [25];
            sprintf(temp, "p:<%u>, item: %c, at %d\n", data->id, message, data->ptr->size());
            std::cout << temp;
            //std::cout << "hi I'm a producer\n";
            sem_post(&mutex);
            sem_post(&fullCount);
        }
        else{
            sem_post(&fullCount);
            sem_post(&mutex);
            pthread_exit(nullptr);
        }
    }
}

void *consumer(void *arg){
    std::cout << ("spawned consumer\n");
    thread_data *data = (thread_data *)arg;
    while(true){
        char message;
        sem_wait(&fullCount);
        sem_wait(&mutex);
        if(iCount < data->itemcount) {
            message = data->ptr->top(); //SEGFAULT
            char temp[25];
            printf(temp, "c:<%u>, item: %c, at %d\n", data->id, message, data->ptr->size());
            data->ptr->pop();
            std::cout << temp;
            //std::cout << "Hi I'm a consumer\n";
            sem_post(&mutex);
            sem_post(&emptyCount);
        }
        else if (iCount == data->itemcount){
            message = data->ptr->top(); //SEGFAULT
            char temp[25];
            printf(temp, "c:<%u>, item: %c, at %d\n", data->id, message, data->ptr->size());
            data->ptr->pop();
            std::cout << temp;
            sem_post(&emptyCount);
            sem_post(&mutex);
            pthread_exit(nullptr);
        }
        else{
            sem_post(&mutex);
            pthread_exit(nullptr);
        }

    }
}

int main(int argc, char *argv[]){
    int bufferSize = N;
    int pThreadCount,cThreadCount,itemCount;
    for (int x = 0; x < argc; ++x) {
        if(strcmp(argv[x],"-b") == 0){
            bufferSize = atoi(argv[x+1]);
        }
        if(strcmp(argv[x],"-p") == 0){
            pThreadCount = atoi(argv[x+1]);
        }
        if(strcmp(argv[x],"-c") == 0){
            cThreadCount = atoi(argv[x+1]);
        }
        if(strcmp(argv[x],"-i") == 0){
            itemCount = atoi(argv[x+1]);
        }
    }
    sem_init(&mutex,1,1);
    sem_init(&fullCount,1,0);
    sem_init(&emptyCount,1,bufferSize);

    std::stack<char> myStack;
    pthread_t myPThreads[pThreadCount];
    thread_data thrData[pThreadCount];
    pthread_t myCThreads[cThreadCount];
    thread_data cThrData[cThreadCount];

    for (int i = 0; i < pThreadCount; ++i) {
        thrData[i].id = i;
        thrData[i].itemcount = itemCount;
        thrData[i].ptr = &myStack;
        pthread_create(&myPThreads[i], NULL, producer, &thrData[i]);
    }
    for (int i = 0; i < cThreadCount; ++i) {
        cThrData[i].id = i;
        cThrData[i].itemcount = itemCount;
        thrData[i].ptr = &myStack;
        pthread_create(&myCThreads[i], NULL, consumer, &cThrData[i]);
    }

    for (int k = 0; k < pThreadCount; ++k) {
        pthread_join(myPThreads[k], NULL);
    }
    for (int j = 0; j < cThreadCount; ++j) {
        pthread_join(myCThreads[j], NULL);
    }

    return 0;
}

2 个答案:

答案 0 :(得分:1)

iCount <= data->itemcount始终为真。 consumer从不退出循环。在某个时候,它耗尽了堆栈,随后的top()调用表现出未定义的行为。

答案 1 :(得分:0)

对于任何cThrData[i].ptr

i从未初始化。 consumer通过未初始化的指针调用top(),此程序表现出未定义的行为。