详解C++11中的线程库
C++11引入了线程库,这使得C++程序员可以轻松地编写多线程应用程序。线程库提供了一个标准化的方式来执行并发任务和同步不同线程之间的访问。
基础概念
线程的创建和执行
线程是计算机系统执行的最小的单位。在C++11中,线程的创建和执行非常简单,并且通过std::thread类实现。
我们可以使用std::thread对象的构造函数来创建一个新的线程,并传递一个可以执行的函数作为参数。如果这个函数需要参数,可以将参数通过std::ref传递给std::thread构造函数。
以下是一个简单的例子:
#include <iostream>
#include <thread>
void HelloFunction()
{
std::cout << "Hello from a thread!" << std::endl;
}
int main()
{
std::thread t(HelloFunction);
t.join();
return 0;
}
在这个例子中,我们创建了一个名为t的线程,并通过HelloFunction函数作为参数来启动该线程。该线程执行HelloFunction函数并输出一条消息。在main函数最后,我们对线程进行了等待操作,确保线程执行完成后程序才继续执行。
线程的同步
在多线程的环境下,线程之间需要进行同步来保证共享资源的正确性,即只有一个线程能够访问共享资源。C++11提供了多种同步机制来实现线程同步。
- Mutex:互斥量(Mutual Exclusion)控制对共享资源的访问。在某个线程访问共享资源时,可以加锁( lock() ),当操作结束后解锁( unlock() ),使得其它的线程可以访问该共享资源。
下面这个例子演示了如何使用std::mutex来保护共享变量的访问:
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mtx; //锁对象
void PrintNum(int i)
{
mtx.lock();
std::cout << "Thread " << std::this_thread::get_id() << " executed i= " << i << std::endl;
mtx.unlock();
}
int main()
{
std::thread t[10];
for (int i = 0; i < 10; i++)
{
t[i] = std::thread(PrintNum, i);
}
for (int i = 0; i < 10; i++)
{
t[i].join();
}
return 0;
}
在这个例子中,我们使用std::mutex对象mtx来保护共享的PrintNum函数。在每个线程中访问共享变量i之前使用mtx.lock()进行加锁,在对i的访问结束后使用mtx.unlock()解锁,在多线程环境中(多线程可能同时访问i),互斥锁保证了i的访问操作是线程安全的。
- Condition Variable:条件变量在等待某种条件满足时,可以让线程进入等待状态,并在条件得到满足时唤醒线程。
下面这个例子演示了如何使用std::condition_variable:
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
std::mutex mtx;
std::condition_variable cv;
bool dataReady = false;
void WorkerThread()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lock(mtx);
dataReady = true;
std::cout << "Worker thread signals data ready!" << std::endl;
}
cv.notify_one();
}
int main()
{
std::thread workerThread(WorkerThread);
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return dataReady; });
}
std::cout << "Main thread got notified!" << std::endl;
workerThread.join();
return 0;
}
在这个例子中,我们首先创建了一个子线程,并通过std::condition_variable对象cv来等待数据的到来。在子线程中,当数据准备好的时候设置bool变量dataReady为true并调用cv.notify_one()唤醒().在主线程中,使用std::unique_lock
总结
C++11中的线程库提供了一种简单的方式来编写多线程应用程序。本文介绍了线程的创建和执行,同时还讨论了线程同步的机制,如mutual exclusion和条件变量。这些机制为我们提供了一种可重用的方式来保护共享资源并确保线程安全。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解C++11中的线程库 - Python技术站