c++ - Pthread段错误在main中使用指向变量的指针
问题描述
我是 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;
}
解决方案
iCount <= data->itemcount
总是正确的。consumer
永远不会退出循环。在某些时候,它会耗尽堆栈,随后的top()
调用会表现出未定义的行为。
推荐阅读
- static - 如果 gstreamer-1.16 构建为静态库,则 gst-inspect-1.0 失败并显示“g_once_init_leave: assertion 'result != 0' failed”
- ios - 下载数据期间集合视图中的图像发生变化
- postgresql - PostGIS 表索引
- javascript - 我们可以在 MSAL JS 中使用响应类型作为访问令牌进行身份验证吗
- javascript - Ionic 3 未定义但不是未定义
- asp.net-core - 使用 xUnit 测试依赖注入范围“一致性”
- css - 用css重排多行多列
- python - 如何解决 Int 对象不可下标错误
- apache-kafka - KTable 未触发
- docker - 如何使用“webdis docker image”向主机公开 redis-server 端口