多线程-条件变量

条件变量是一个能够阻止调用线程直到通知恢复的对象。

它使用unique_lock(通过互斥锁)在调用其中一个等待函数时锁定线程。线程保持阻塞状态,直到被另一个调用相同condition_variable对象上的通知函数的线程唤醒。

condition_variable类型的对象总是使用unique_lock 来等待:对于适用于任何类型的可锁定类型的替代,请参阅condition_variable_any

condition_variable()构造函数

default (1)
condition_variable();
copy [deleted] (2)
condition_variable (const condition_variable&) = delete;

 作用:构造一个条件变量对象。条件变量没有复制和赋值构造函数。

wait()成员函数

unconditional (1)
void wait (unique_lock& lck);
predicate (2)
template 
  void wait (unique_lock& lck, Predicate pred);

当前线程(应锁定lck的互斥锁)的执行被阻止,直到通知为止。在阻塞线程的那一刻,该函数自动调用lck.unlock(),允许其他锁定的线程继续。

一旦被notified()(显式地,由其他一些线程),该函数解除阻塞并调用lck.lock(),使lck处于与调用函数时相同的状态。然后函数返回(注意,最后一个互斥锁定可能会在返回之前再次阻塞线程)

通常,另一个线程调用notify_one()或者成员函数notify_all(),唤醒被阻塞的线程,然后线程获得互斥锁。但某些实现可能会产生虚假的唤醒调用,而不会调用任何这些函数。因此,该功能的用户应确保满足其恢复条件。

在(2)中,如果如果pred返回false,该函数仅阻止,并且只有当pred为true时才发出通知,解除阻塞。

参数说明:lck  -- 一个unique_lock对象,并且它的mutex object 被当前线程 locked;

                  pred --一个不带参数的可调用对象或函数,返回一个可以作为bool计算的值。 重复调用它直到它的计算结果为true。

// condition_variable::wait (with predicate)
#include            // std::cout
#include              // std::thread, std::this_thread::yield
#include               // std::mutex, std::unique_lock
#include  // std::condition_variable

std::mutex mtx;
std::condition_variable cv;

int cargo = 0;
bool shipment_available() {return cargo!=0;}

void consume (int n) {
  for (int i=0; i lck(mtx);
    cv.wait(lck,shipment_available);
    // consume:
    std::cout << cargo << '\n';
    cargo=0;
  }
}

int main ()
{
  std::thread consumer_thread (consume,10);

  // produce 10 items when needed:
  for (int i=0; i<10; ++i) {
    while (shipment_available()) std::this_thread::yield();
    std::unique_lock lck(mtx);
    cargo = i+1;
    cv.notify_one();
  }

  consumer_thread.join();

  return 0;
}

Output:

1
2
3
4
5
6
7
8
9
10

 

你可能感兴趣的:(C++)