Saj*_*ani 33 c c++ multithreading synchronization shared-memory
如何在Java中等待和通知在C/C++中两个或多个线程之间的共享内存?我使用pthread库.
Ste*_*sop 36
您需要两个对象:互斥锁和条件变量,而不是您将用于等待/通知的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中一样,可以从等待函数中进行虚假唤醒,因此您需要在调用signal之前设置一些条件,并在等待调用之后进行检查,并且需要pthread_cond_wait在循环中调用.与在Java中一样,在您等待时释放互斥锁.
与Java不同,notify除非您握住监视器,否则无法呼叫,您实际上可以在pthread_cond_signal不保持互斥锁的情况下进行呼叫.但是,它通常不会获得任何东西,并且通常是一个非常糟糕的主意(因为通常你想要锁定 - 设置条件 - 信号 - 解锁).所以最好只是忽略它并像Java一样对待它.
它没有更多的东西,基本模式与Java相同,而不是巧合.但是,请阅读所有这些功能的文档,因为您需要了解和/或避免各种标记和有趣的行为.
在C++中,您可以比使用pthreads API做得更好.您至少应该将RAII应用于互斥锁定/解锁,但是根据您可以使用的C++库,您可能最好使用更多的C++ - ish包装器来实现pthreads功能.
在你的标题中,你将C和C++混合在一起,随便进入"C/C++".我希望,你不是在写一个两者混合的程序.
如果你正在使用C++ 11,你会发现一个可移植的(因为C++,所以)更安全/更容易使用的替代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();
}
Run Code Online (Sandbox Code Playgroud)
此代码还强调了C++对C的一些其他优势: