gpt4 book ai didi

C++ 线程 : cannot unlock mutex in array after condition_variable wait

转载 作者:行者123 更新时间:2023-11-30 05:28:33 24 4
gpt4 key购买 nike

我正在尝试将一个主线程与 N 个子线程同步。阅读之后,我使用了 condition_variableunique_lock。但是,在 OS X 中,我总是收到错误 condition_variable::wait: mutex not locked: Operation not permittedunique_lock::unlock: not locked: Operation not permitted。在 Linux 中,我只得到 Operation not permitted

更清楚一点:我的目标是获得一系列打印:

main thread, passing to 0
thread 0, passing back to main
main thread, passing to 0
thread 0, passing back to main
...

对于四个线程中的每一个。

我改编了 http://en.cppreference.com/w/cpp/thread/condition_variable 中的示例代码.此示例在 wait 之后使用了 unlock,并且它只与除 main (N=1) 之外的一个线程一起工作。但是当适应与 N>1 线程一起工作时,就会发生上述错误。

Yam Marcovic 在评论中说我不应该使用 unlock。但是,为什么 cppreference 示例要使用它呢?为什么它在一个主线程和一个其他线程上运行良好?

代码如下:

#include <cstdio>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;

constexpr int N_THREADS = 4;
constexpr int N_ITER = 10;

bool in_main[N_THREADS] = {false};

void fun(mutex *const mtx, condition_variable *const cv, int tid){
for(int i=0; i<N_ITER; i++) {
unique_lock<mutex> lk(*mtx);
// Wait until in_main[tid] is false
cv->wait(lk, [=]{return !in_main[tid];});
// After the wait we own the lock on mtx, which is in lk
printf("thread %d, passing back to main\n", tid);
in_main[tid] = true;
lk.unlock(); // error here, but example uses unlock
cv->notify_one();
}
}

int main(int argc, char *argv[]) {
// We are going to create N_THREADS threads. Create mutexes and
// condition_variables for all of them.
mutex mtx[N_THREADS];
condition_variable cv[N_THREADS];
thread t[N_THREADS];
// Create N_THREADS unique_locks for using the condition_variable with each
// thread
unique_lock<mutex> lk[N_THREADS];
for(int i=0; i<N_THREADS; i++) {
lk[i] = unique_lock<mutex>(mtx[i]);
// Create the new thread, giving it its thread id, the mutex and the
// condition_variable,
t[i] = thread(fun, &mtx[i], &cv[i], i);
}

for(int i=0; i < N_ITER*N_THREADS; i++) {
int tid=i % N_THREADS; // Thread id
// Wait until in_main[tid] is true
cv[tid].wait(lk[tid], [=]{return in_main[tid];});
// After the wait we own the lock on mtx[tid], which is in lk[tid]
printf("main thread, passing to %d\n", tid);
in_main[tid] = false;
lk[tid].unlock(); // error here, but example uses unlock
cv[tid].notify_one();
}
for(int i=0; i<N_THREADS; i++)
t[i].join();
return 0;
}

示例输出:

thread 0, passing back to main
main thread, passing to 0
thread 1, passing back to main
thread 0, passing back to main
main thread, passing to 1
thread 2, passing back to main
thread 1, passing back to main
main thread, passing to 2
thread 2, passing back to main
thread 3, passing back to main
main thread, passing to 3
main thread, passing to 0
thread 3, passing back to main
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: unique_lock::unlock: not locked: Operation not permitted
Abort trap: 6

最佳答案

您正在尝试 unlock你的互斥量很多次!仔细看代码:

 for(int i=0; i < N_ITER*N_THREADS; i++) {
int tid=i % N_THREADS; // Thread id

哪里N_ITER是 10 和 N_THREADS总是 4,因为它们是 constexpr
我们得到:

 for(int i=0; i < 40; i++) {
int tid=i % 4; // Thread id

所以,当i = 0 lk[0] 中的互斥锁解锁,然后当i=4然后tid = 4%4又一次tid = 0你又在解锁它! std::system_error在这种情况下被抛出。

此外,为什么所有这些 C 指针都是如此?它不像它们中的任何一个可以在任何时候为空..切换到引用..

此外,通常在处理数组索引时,惯例是使用 size_t而不是 int .

关于C++ 线程 : cannot unlock mutex in array after condition_variable wait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36765395/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com