mutex 相关问题

互斥(“互斥”)是一种在多个线程同时访问(特别是更改)相同数据或资源时确保完整性的机制。

如何使用 POSIX 线程声明递归互斥体?

我对如何使用 pthread 声明递归互斥锁有点困惑。 我尝试做的是一次只有一个线程能够运行一段代码(包括函数)但是在怀疑之后我

回答 4 投票 0

什么时候需要 pthread_mutex_destroy?

想问一下pthread_mutex_t的正确用法。 我知道您可以使用 pthread_mutex_init 函数进行初始化,也可以将其设置为 PTHREAD_MUTEX_INITIALIZER 并且

回答 0 投票 0

互斥解锁会隐式通知其他线程吗?

想象一下,我们有一个条件变量 cv_ 与互斥量 mtx_ 相关联 线程 t1 现在有一个与 mtx_ 关联的 unique_lock ul 并且它现在有 cv_,而其他线程是 cv_.wait(unique_lock(mtx_)...

回答 0 投票 0

C 多线程 | for 循环中的线程创建使用上次迭代的参数

我是多线程的新手,一般来说不是 C 语言中最好的,所以对我来说很简单。 我有一个 for 循环,它创建了许多线程,我将参数传递给这些线程: 对于(int i = 0; i <

回答 2 投票 0

如何在 C++ 代码中运行多线程

我是c++的初学者。我编写了一个程序来从一个数据库中提取数据并将这些数据存储到另一个数据库中。我只想添加多个线程来加快进程。我希望通过两种方式做到这一点。

回答 3 投票 0

如何在 golang 中使函数线程安全

如何在golang中锁定一个函数或函数体不被两个线程调用? 我的用例是我有一个网络服务器正在调用一个串行接口,它只能有一个调用...

回答 4 投票 0

我是 pthreads 的新手并将它们与互斥锁一起使用。谁能指出我如何使用它们的正确方向?

我有一个使用 pthreads 和 mutex 的编程作业。该程序的重点是接收输入(.txt 文件),输入如下所示: 桥接数字1 数字2 CarOrBoat CoB_name ...

回答 0 投票 0

std::lock_guard<std::mutex> 和 if constexpr 块的问题

有一个类模板Foo。对于某些特定类型,函数应该使用 lock_guard。 这是示例代码: #包括 #包括 #包括 有一个类模板Foo<T>。对于某些特定类型,函数应该使用lock_guard。 这是示例代码: #include <type_traits> #include <mutex> #include <vector> template<typename T> class Foo { public: void do_something(int k) { if constexpr(std::is_same_v<T, NeedMutexType>) { std::lock_guard<std::mutex> lock(mtx_); } resource_.push_back(k); // code for task with resource_ ... } private: std::mutex mtx_; std::vector<int> resource_; }; std::lock_guard 将在 if constexpr 范围的末尾被破坏。 (如有不妥,请指正。) 为了处理这个问题,我可以将下面带有 resource_ 的任务代码复制到 if constexpr 范围内,或者只使用原始的 std::mutex,例如 mtx_.lock() & mtx_.unlock() 代替。 有什么方法可以用std::lock_guard处理这个问题吗?谢谢。 也许 std::conditional 可以来拯救这里,如果你需要经常做这种事情。 template<class Mutex> struct FakeLockGuard { FakeLockGuard(Mutex&){} }; template<typename T, class Mutex = std::mutex> using OptionalLock = typename std::conditional< std::is_same_v<T, NeedMutexType>, std::lock_guard<Mutex>, FakeLockGuard<Mutex>>::type; 这里我们定义了一个什么都不做的类模板,其构造方式与std::lock_guard相同。然后,我们将其与 std::conditional 结合使用,根据类型检查的结果选择 std::lock_guard 或 FakeLockGuard。 现在您可以按如下方式使用它: template<typename T> class Foo { public: void do_something(int k) { OptionalLock<T> lock(mtx_); resource_.push_back(k); // ... } private: std::mutex mtx_; std::vector<int> resource_; }; 您可以通过在 FakeLockGuard 构造函数中设置断点或使其输出一些内容来轻松验证它是否有效。 这就是你如何让它在编译时工作。但是我认为正如您已经提到的那样,您可以简单地构造一个unique_lock然后有条件地锁定它。这样做的好处是对于必须使用您的代码的任何人来说都更加清晰。最后,就看你觉得哪个最合适了。 只需在解锁状态下构建锁,然后再锁定: template<typename T> class Foo { public: void do_something(int k) { std::unique_lock<std::mutex> lock(mutex_, std::defer_lock); if constexpr(std::is_same_v<T, NeedMutexType>) { lock.lock(); } resource_.push_back(k); // code for task with resource_ ... } private: std::mutex mtx_; std::vector<int> resource_; } 请注意,您需要为此使用std::unique_lock,因为std::lock_guard无法解锁

回答 2 投票 0

C++ 线程同步互斥锁

我是并行编程的新手,我正在尝试分解多线程上的迭代矩阵计算:每次迭代由两个顺序作业 A 和 B 组成;它需要等待所有...

回答 2 投票 0

Rust:不能将 `Arc` 中的数据借用为可变的,但内部数据通过 Mutex 保护

在学习 Rust 并尝试完成一个示例时,其中需要跨线程和函数共享数据库 Db。 链接到最小示例 我已经包装了数据库(一个结构...

回答 1 投票 0

为什么我的程序在没有线程的情况下运行良好,但在添加线程时却表现异常?

我的程序模拟 grep 命令的行为。即执行./main grep 时,会使用缓冲区逐行查找,并写入行号...

回答 1 投票 0

将异步闭包应用于互斥体内容的组合器?

在我的想法中,run 函数无法编译,因为闭包的返回类型取决于可变引用的生命周期。我无法表达 F 的正确界限,这会 f...

回答 0 投票 0

多线程单生产者多消费者错误

我的生产者和消费者实施使用互斥锁和条件变量时遇到问题。 问题是程序有时永远不会完成,有时会完成,但消耗了

回答 0 投票 0

pthread_cond_wait()如何与mutex解耦?

我一直在思考条件变量背后的逻辑,并且对与之相关的最常见问题感到满意。 基本上,如果我们做类似的事情: mutex.lock() whi...

回答 1 投票 0

想不出怎么用python写两个老师的线程队列

我被分配了一个任务:创建一个项目“Laboratory work”,模拟学生交付实验室作业。 在课程开始时,假设学生接受实验室...

回答 1 投票 0

在 java.lang.Object kotlin.SynchronizedLazyImpl.getValue()(LazyJVM.kt:69) waiters=5

我读过这可能是“所有者方法的长时间监视器争用事件”的原因? 它说我应该查看要求锁定的位置。所以,它是 kotlin stdlib 的 LazyJVM.kt:69。 这是

回答 0 投票 0

使用互斥锁解决有界缓冲区问题

这里是新手。我正在对 C 编程中的有界缓冲区问题进行分配。我尽可能不使用库来更好地理解解决方案。 到目前为止我有这个 #包括...

回答 1 投票 0

C 信号量如何提供互斥(内部)?

我知道这个理论以及为什么使用它们,问题是针对它的内部功能,因为我认为信号量只不过是一个全局变量或文件,SO如何管理

回答 0 投票 0

c++中的条件变量,我该如何正确使用它们?

我正在尝试实现一个工作对象(这是一个等待任务并仅在销毁时终止的线程),但我在使用 std::condition_variable 时遇到了问题: #包括 我正在尝试实现一个工作对象(这是一个等待任务并仅在销毁时终止的线程),但是我在使用std::condition_variable: #include <thread> #include <mutex> #include <condition_variable> #include <functional> #include <atomic> #include <iostream> class Worker { public: Worker(Worker&&) = delete; Worker(const Worker&) = delete; Worker() : stop(false) , thread(&Worker::worker_thread, this) {} void push(std::function<void()> _f) { std::unique_lock lock(thread_mutex); task = std::move(_f); new_task.notify_one(); } ~Worker() { /* not implemented yet */ } private: void worker_thread() { std::unique_lock lock(thread_mutex); while (true) { new_task.wait(lock); if (stop) return; task(); } } std::atomic<bool> stop; std::function<void()> task; std::thread thread; std::mutex thread_mutex; std::condition_variable new_task; }; 我在这里想出了这个目前不适用于 gcc 的例子: int main() { Worker t; t.push([] { std::cout << "Hello from worker" << std::endl; }); for (int i = 0; i < 10; ++i) t.push([i] { std::cout << i << std::endl; }); return 0; } 如果运行代码我得到这个输出: terminate called without an active exception //(because destructor yet to be implemented) 9 9 9 9 9 . . . and so on 9 所以这是我的代码应该如何工作: 当构造一个Worker对象时,它会产生一个执行worker_thread函数的线程。 此函数锁定thread_mutex,并且应该仅在等待条件变量时将其解锁。 当一个任务被推送时,push 函数会尝试锁定互斥量,它应该只在它可以的时候,也就是当 worker_thread 正在等待带有条件变量的任务时。 所以如果线程正在等待,push应该能够获取锁并在task缓冲区中移动新任务,然后通知条件变量,唤醒线程。 一个提示是这段代码: int main() { Worker t; t.push([] { std::cout << "Hello from worker" << std::endl; }); //for (int i = 0; i < 10; ++i) // t.push([i] { std::cout << i << std::endl; }); return 0; } 永远打招呼,有时它会崩溃,但应该只打印一次然后等待下一个任务。 这更奇怪,因为我最初的想法是一个接一个地执行多个推送会出现问题,也许这可能会导致锁出现一些问题,但在最后一个示例中,我只调用了一次push 并且仍然我有问题。 有人能明白问题出在哪里吗? 阅读有关初始化顺序的信息。当 thread_mutex 和 new_task 尚未初始化时,您运行一个线程。使用未初始化的成员运行 worker_thread 是未定义的行为。 Worker 构造,推送任务,销毁可以在线程工作者启动之前发生,并且工作者永远等待条件变量。您应该首先使用相反方向的条件变量来向构造函数发出有关正在运行的工作人员的信号。 这是适用于两个示例的解决方案: class Worker { public: Worker(Worker&&) = delete; Worker(const Worker&) = delete; Worker() : stop(false) , task(nullptr) , thread(&Worker::worker_thread, this) {} void push(std::function<void()> _f) { std::unique_lock lock(thread_mutex); cv.wait(lock, [this] { return !task; }); task = std::move(_f); new_task.notify_one(); } ~Worker() { std::unique_lock lock(thread_mutex); cv.wait(lock, [this] { return !task; }); stop = true; new_task.notify_one(); lock.unlock(); if (thread.joinable()) thread.join(); } private: void worker_thread() { std::unique_lock lock(thread_mutex); while (true) { cv.wait(lock, [this] { return task || stop; }); // if (stop) return; task(); task = nullptr; // reset task for check new_task.notify_one(); } } bool stop; // does not need to be atomic std::function<void()> task; std::mutex thread_mutex; std::condition_variable cv; std::thread thread; // moved to bottom }; 我遇到的主要问题是我不明白条件变量是如何工作的。 条件变量不等待信号,它等待条件。 所以偶尔条件变量会“唤醒”线程,检查条件是否满足是用户的责任。 使用条件变量时,检查条件很重要,否则它会时不时地唤醒并运行之后的操作。 所以这样做的一种方法是: while (!condition) cv.wait(lock); 或者这个,使用 lambdas: cv.wait(lock, [] { return condition; }); 所以cv.notify_one()只是一个条件可能已经改变的提示,而不是唤醒线程的命令。 此外,我必须小心初始化,因为在我之前的代码中,线程是在条件变量和互斥锁之前初始化的,在这种情况下是否有所不同尚不清楚,它可能确实如此。 成员变量按照声明的顺序进行初始化。 最后,我还需要检查push 和析构函数中的另一个条件。我需要在两者中都看到任务无效,或者设置为 0 或 NULL. 这是因为如果设置为NULL,就意味着push函数可以安全的修改worker_thread未使用的任务。 析构函数做类似的事情,它需要在销毁之前查看线程是否执行完最后一个任务,将stop标志设置为true, 那是因为工作人员在执行任务之前检查是否设置了标志。 就这些,谢谢大家的热心帮助,希望这个问题对所有需要了解条件变量的程序员有所帮助

回答 2 投票 0

如何使 Flutter 桌面应用程序成为单实例?

我有一个 Flutter 桌面应用程序,想防止它的多个实例同时运行。为此,我尝试使用 package:mutex 中的 Mutex,但它不起作用。任何人都可以

回答 0 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.