C++ 如何在另一个线程中创建互斥?

C++ 如何在另一个线程中创建互斥?,c++,multithreading,mutex,C++,Multithreading,Mutex,我想在循环中创建一个线程,当创建线程时,在线程完成之前不要再创建它。我使用下面的代码,但它不工作,因为互斥锁将在已经解锁时解锁。谁能告诉我怎么做 #include <iostream> #include <thread> #include <mutex> int counter = 0; std::mutex mtx; std::thread t; void test_mutex_t2() { std::lock_guard<std::mutex&

我想在循环中创建一个线程,当创建线程时,在线程完成之前不要再创建它。我使用下面的代码,但它不工作,因为互斥锁将在已经解锁时解锁。谁能告诉我怎么做

#include <iostream>
#include <thread>
#include <mutex>

int counter = 0;
std::mutex mtx;
std::thread t;

void test_mutex_t2()
{
 std::lock_guard<std::mutex> lock(mtx);
 counter++;
}

void test_mutex_t1()
{
 while (1) {
   if (mtx.try_lock())
   {
     t = std::thread(test_mutex_t2);    
     mtx.unlock();
   }
 }
}

int main()
{
  test_mutex_t1();
  return 0;
}
#包括
#包括
#包括
int计数器=0;
std::互斥mtx;
标准:螺纹t;
无效测试\u互斥锁\u t2()
{
标准:锁和防护锁(mtx);
计数器++;
}
无效测试\u互斥体\u t1()
{
而(1){
如果(mtx.try_lock())
{
t=std::thread(测试互斥体t2);
mtx.unlock();
}
}
}
int main()
{
test_mutex_t1();
返回0;
}

std::thread
必须
分离
连接

std::mutex mtx;
std::thread t;

void test_mutex_t2()
{
    std::lock_guard<std::mutex> lock(mtx);
    counter++;
}

void test_mutex_t1()
{
    while (1) {
        if (mtx.try_lock())
        {
            t = std::thread(test_mutex_t2);
            t.detach();
            mtx.unlock();
        }
    }
}
std::mutex-mtx;
标准:螺纹t;
无效测试\u互斥锁\u t2()
{
标准:锁和防护锁(mtx);
计数器++;
}
无效测试\u互斥体\u t1()
{
而(1){
如果(mtx.try_lock())
{
t=std::thread(测试互斥体t2);
t、 分离();
mtx.unlock();
}
}
}

听起来您实际上想要的是在任何时候都只运行一个后台线程。如果这是真的,我建议完全去掉锁,在退出循环之前选择
join()
线程。大概是这样的:

while (true) {
    auto thr = std::thread(test_mutex_t2);
    thr.join(); // Will block until thread exits
}
void thread_func(std::condition_variable* cv) {
     // do work
     cv->notify_one();
}

int main(void) {
     std::condition_variable cv;
     std::mutex lock;
     while (true) {
         std::unique_lock<std::mutex> lock(mut);
         auto thr = std::thread(thread_func, &cv);
         cv.wait(lock); // Wait for background thread to notify us
         thr.join();
     }
}
然而,我还想指出,这意味着您将只运行一个线程。这就提出了一个问题,为什么要使用线程呢?您正在生成额外的线程来完成同步工作

如果确实需要多个线程,则需要不同的同步原语。从根本上说,互斥锁旨在保护对单个资源的访问。您要做的是从后台线程到主线程进行通信,在后台线程完成某项工作(在本例中,已完成)时通知主线程。这通常通过条件变量或信号量来实现。
std::condition\u变量
类实现了其中的第一个变量

我建议向thread函数传递一个条件变量,它使用该变量在完成时向主线程发出警报。大概是这样的:

while (true) {
    auto thr = std::thread(test_mutex_t2);
    thr.join(); // Will block until thread exits
}
void thread_func(std::condition_variable* cv) {
     // do work
     cv->notify_one();
}

int main(void) {
     std::condition_variable cv;
     std::mutex lock;
     while (true) {
         std::unique_lock<std::mutex> lock(mut);
         auto thr = std::thread(thread_func, &cv);
         cv.wait(lock); // Wait for background thread to notify us
         thr.join();
     }
}
void thread\u func(标准::条件变量*cv){
//工作
cv->notify_one();
}
内部主(空){
std::条件变量cv;
std::互斥锁;
while(true){
std::唯一锁定(mut);
自动thr=std::thread(thread_func,&cv);
cv.wait(lock);//等待后台线程通知我们
thr.join();
}
}

同样,对于这个简单的例子来说,这是过分的;我会像上面那样使用
join()
方法。但是如果您想要一个更复杂的通信模式,其中主线程需要在多个位置等待后台线程,那么条件变量更合适。

Thx获取答案。但我不想在线程运行时阻塞循环!在这种情况下,使用两个互斥锁怎么样?我编辑了代码accordingly@emcute0319你“不想阻止循环”是什么意思?循环所做的只是创建一个线程,为什么要关心它是否被阻塞?是不是做其他的工作?是的,这只是一个小测试。我不熟悉C++。所以我做了测试。这不是解决方案。有一个比赛条件。主线程可能会解锁互斥锁,
try\u lock
调用可能会成功,并且在后台线程获取互斥锁之前,可能会创建另一个线程。为什么要使用
try\u lock()
而不是
lock()
?什么意思,“互斥锁将在其已解锁时解锁?”听起来你只想运行一个线程,对吗?如果是这样的话,那么创建一个循环并在循环结束时调用它的
join
方法似乎更简单。我只想创建一个线程来做大量的事情,比如图像识别,但是主循环不能被阻塞,当一个线程创建后,主循环不能创建另一个线程。谢谢你的通知。你可以让你的线程继续运行,只要在它完成工作时给它一批新的数据就行了吗?(查阅“生产者-消费者”)