如何在 C/C++ 中的 Java 中等待和通知两个或多个线程之间的共享内存?我使用 pthread 库。
原文由 Sajad Bahmani 发布,翻译遵循 CC BY-SA 4.0 许可协议
如何在 C/C++ 中的 Java 中等待和通知两个或多个线程之间的共享内存?我使用 pthread 库。
原文由 Sajad Bahmani 发布,翻译遵循 CC BY-SA 4.0 许可协议
在您的标题中,您将 C 和 C++ 如此随意地混合为“C/C++”。我希望,您编写的程序不是两者的混合体。
如果您使用的是 C++11,您会发现 pthreads 的可移植替代品(在 POSIX 系统上,它通常在底层使用 pthreads)。
您可以使用 std::condition_variable
+ std::mutex
等待/通知。 这个例子 展示了如何:
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex m;
std::condition_variable cv;
std::string data;
bool mainReady = false;
bool workerReader = false;
void worker_thread()
{
// Wait until main() sends data
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return mainReady;});
}
std::cout << "Worker thread is processing data: " << data << std::endl;
data += " after processing";
// Send data back to main()
{
std::lock_guard<std::mutex> lk(m);
workerReady = true;
std::cout << "Worker thread signals data processing completed\n";
}
cv.notify_one();
}
int main()
{
std::thread worker(worker_thread);
data = "Example data";
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
mainReady = true;
std::cout << "main() signals data ready for processing\n";
}
cv.notify_one();
// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return workerReady;});
}
std::cout << "Back in main(), data = " << data << '\n';
// wait until worker dies finishes execution
worker.join();
}
原文由 Domi 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
您需要两个对象,而不是用于等待/通知的 Java 对象:互斥体和条件变量。这些初始化为
pthread_mutex_init
和pthread_cond_init
。如果您需要在 Java 对象上进行同步,请使用
pthread_mutex_lock
和pthread_mutex_unlock
(请注意,在 C 中您必须自己手动配对)。如果您不需要等待/通知,只需锁定/解锁,那么您不需要条件变量,只需互斥锁。请记住,互斥锁不一定是“递归的”,这意味着如果您已经持有锁,除非您设置 init 标志来表示您想要该行为,否则您将无法再次使用它。如果您会调用
java.lang.Object.wait
,请调用pthread_cond_wait
或pthread_cond_timedwait
。如果您会调用
java.lang.Object.notify
,请调用pthread_cond_signal
。如果您会调用
java.lang.Object.notifyAll
,请调用pthread_cond_broadcast
。与在 Java 中一样,等待函数可能会产生虚假唤醒,因此您需要在调用信号之前设置一些条件,并在调用等待之后检查,并且您需要在循环中调用
pthread_cond_wait
.与在 Java 中一样,互斥锁在您等待时被释放。与 Java 不同,您不能调用
notify
除非您持有监视器,您实际上 可以 调用pthread_cond_signal
而不持有互斥锁。但是,它通常不会为您带来任何好处,而且通常是一个非常糟糕的主意(因为通常您想要锁定 - 设置条件 - 信号 - 解锁)。所以最好只是忽略它,像 Java 一样对待它。没有更多的东西,基本模式与 Java 相同,并非巧合。不过,请阅读所有这些功能的文档,因为您想了解和/或避免各种标志和有趣的行为。
在 C++ 中,您可以比仅使用 pthreads API 做得更好。您至少应该将 RAII 应用于互斥锁/解锁,但根据您可以使用的 C++ 库,您最好为 pthreads 函数使用更 C++ 的包装器。