简体   繁体   English

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

[英]How to make a mutex in another thread?

I want to create a thread in a loop, and when the thread is created, don't create it again until the thread is done.我想在一个循环中创建一个线程,当线程创建时,在线程完成之前不要再次创建它。 I use the code below, but it's not working, because the mutex will unlock while it's already unlocked.我使用下面的代码,但它不起作用,因为互斥锁会在它已经解锁时解锁。 Can anyone tell me how to do?谁能告诉我怎么办?

#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;
}

std::thread have to detach or join : std::thread必须detachjoin

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();
        }
    }
}

It sounds like what you actually want is to have exactly one background thread running at any time.听起来您真正想要的是随时运行一个后台线程。 If that's true, I would suggest getting rid of the locks entirely, opting instead to join() the thread before exiting the loop.如果这是真的,我建议完全摆脱锁,在退出循环之前选择join()线程。 Something like this:像这样的东西:

while (true) {
    auto thr = std::thread(test_mutex_t2);
    thr.join(); // Will block until thread exits
}

However, I'd also like to point out that this means you'll have exactly one thread running.不过,我也想指出,这意味着你将有一个确切的线程中运行。 This raises the question, why are you using threads at all?这就提出了一个问题,你为什么要使用线程? You're spawning extra threads just to do synchronous work.您生成额外的线程只是为了进行同步工作。

If you really do want multiple threads, you need a different synchronization primitive.如果您确实需要多个线程,则需要不同的同步原语。 Fundamentally, a mutex is designed to protect access to a single resource.从根本上说,互斥锁旨在保护对单个资源的访问。 What you want to do is communicate from the background thread to the main thread, notifying the main thread when the background thread has done something (finished, in this case).你要做的是从后台线程传递给主线程,通知在后台线程所做的事(成品,在这种情况下)主线程什么。 This is usually accomplished with a condition variable or a semaphore.这通常通过条件变量或信号量来完成。 The std::condition_variable class implements the first of these. std::condition_variable类实现了第一个。

I would recommend passing the thread function a condition variable, which it uses to alert the main thread when it is finished.我建议向线程函数传递一个条件变量,它用于在完成时提醒主线程。 Something like this:像这样的东西:

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();
     }
}

Again, this is overkill for this simple example;同样,这对于这个简单的例子来说太过分了; I would use the join() method as above.我会使用上面的join()方法。 But if you want have a more complicated communication pattern, where the main thread needs to wait at multiple places for the background thread, the condition variable is more appropriate.但是如果你想要一个更复杂的通信模式,主线程需要在多个地方等待后台线程,条件变量更合适。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM