gpt4 book ai didi

c++ - 使用 pthread_create 时出现 "Segmentation fault (core dumped)"

转载 作者:太空宇宙 更新时间:2023-11-04 05:17:01 29 4
gpt4 key购买 nike

所以我遇到了一个问题:当我尝试创建最后一个线程时,它总是说核心已转储。如果我编写创建 5 个或 2 个线程,这并不重要。这是我的代码:UPD:现在我不能执行超过 3 个线程,并且线程不执行我希望它们执行的功能(消费和生产)

UPD_2:现在我收到了这样的消息:在抛出“递归调用的终止”实例后终止调用终止递归调用中止(核心转储)

 #include<cstdlib>
#include <iostream>
#include <string>
#include <mutex>
#include <pthread.h>
#include <condition_variable>

#define NUM_THREADS 4

using namespace std;

struct thread_data
{
int thread_id;
int repeat;
};


class our_monitor{
private:
int buffer[100];
mutex m;
int n = 0, lo = 0, hi = 0;
condition_variable in,out;
unique_lock<mutex> lk;

public:
our_monitor():lk(m)
{

}
void insert(int val, int repeat)
{
in.wait(lk, [&]{return n <= 100-repeat;});
for(int i=0; i<repeat; i++)
{
buffer[hi] = val;
hi = (hi + 1) % 100; //ring buffer
n = n +1; //one more item in buffer
}
lk.unlock();
out.notify_one();
}

int remove(int repeat)
{
out.wait(lk, [&]{return n >= repeat;});
int val;
for(int i=0; i<repeat; i++)
{
val = buffer[lo];
lo = (lo + 1) % 100;
n -= 1;
}
lk.unlock();
in.notify_one();
return val;
}
};

our_monitor mon;

void* produce(void *threadarg)
{
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
cout<<"IN produce after paramiters"<< my_data->repeat<<endl;
int item;
item = rand()%100 + 1;
mon.insert(item, my_data->repeat);
cout<< "Item: "<< item << " Was prodused by thread:"<< my_data->thread_id << endl;
}

void* consume(void *threadarg)
{
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
cout<<"IN consume after paramiters"<< my_data->repeat<<endl;
int item;
item = mon.remove(my_data->repeat);
if(item) cout<< "Item: "<< item << " Was consumed by thread:"<< my_data->thread_id << endl;
}

int main()
{
our_monitor *mon = new our_monitor();
pthread_t threads[NUM_THREADS];
thread_data td[NUM_THREADS];
int rc;
int i;

for( i = 0; i < NUM_THREADS; i++ )
{
td[i].thread_id = i;
td[i].repeat = rand()%5 + 1;
if(i % 2 == 0)
{
cout << "main() : creating produce thread, " << i << endl;
rc = pthread_create(&threads[i], NULL, produce, (void*) &td[i]);

if (rc)
{
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
} else
{
cout << "main() : creating consume thread, " << i << endl;
rc = pthread_create(&threads[i], NULL, consume, (void *)&td[i]);

if (rc)
{
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
}
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
//pthread_exit(NULL);

}

UPD:现在我不能执行超过 3 个线程,并且线程不执行我希望它们执行的功能(消费和生产)

UPD_2:现在我收到了这样的消息:在抛出“递归调用的终止”实例后终止调用终止递归调用中止(核心转储)

最佳答案

来自 cppref 关于 std::condition_variable.wait(...)

"Calling this function if lock.mutex() is not locked by the current thread is undefined behavior."

http://en.cppreference.com/w/cpp/thread/condition_variable/wait

不幸的是,程序并没有在第 47 行崩溃,而是在第 55 行崩溃,此时您解锁了未锁定的锁。

enter image description here

enter image description here

进入功能时锁定锁。我已经快速检查了你的其余逻辑,我 85% 确定它在其他方面没问题。

虽然你在这里,但这并不是绝对必要的,但这是一个很好的做法。 std::lock_guard 和 std::unique_lock 在互斥锁进入作用域时自动锁定互斥锁,并在其离开作用域时将其解锁。这有助于简化异常处理和奇怪的函数返回。我建议您摆脱 lk 作为成员变量,并将其用作作用域局部变量。

    void insert(int val, int repeat)
{
{ // Scoped. Somewhat pedantic in this case, but it's always best to signal after the mutex is unlocked
std::unique_lock<std::mutex> lk(m);
in.wait(lk, [&]{return n <= 100-repeat;});
for(int i=0; i<repeat; i++)
{
buffer[hi] = val;
hi = (hi + 1) % 100; //ring buffer
n = n +1; //one more item in buffer
}
}
out.notify_one();
}

好的,现在进入最后一期。生产者/消费者的最酷之处在于我们可以同时生产和消费。然而,我们只是锁定了我们的功能,所以这不再可能。您现在可以做的是将条件锁定/等待/解锁/工作/信号内部移动到for循环

伪代码:

// produce:
while (true)
{
{
unique_lock lk(m)
wait(m, predicate)
}
produce 1
signal
}

这相当于使用信号量(C++'11 STL 没有,但您可以轻松地创建自己的信号量,如上所示。)

// produce:
semaphore in(100);
semaphore out(0);
while (true)
{
in.down(1) // Subtracts 1 from in.count. Blocks when in.count == 0 (meaning the buffer is full)
produce 1
out.up(1) // Adds 1 to out.count
}

关于c++ - 使用 pthread_create 时出现 "Segmentation fault (core dumped)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47860182/

29 4 0
文章推荐: linux - 磁盘 I/O 基准测试
文章推荐: css - HTML
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com