C++11 并发指南之多线程初探
什么是多线程
多线程是指在一个进程中运行的多个不同执行流程,每个执行流程叫做一个线程。多线程可以使程序并行执行,提高程序效率。
为什么要使用多线程
在单线程程序中,程序按照顺序执行,如果程序中出现了耗时的操作,程序就会变得非常慢。使用多线程可以使程序中的耗时操作在不同的线程中执行,从而提高程序的执行效率。另外,多线程也可以使程序变得更加灵活,可以根据需要创建和销毁线程,动态地分配线程的资源等。
如何使用多线程
在C++中,可以使用标准库中的std::thread
来创建和管理线程。以下是一个示例程序:
#include <iostream>
#include <thread>
void sayHello() {
std::cout << "Hello, World!" << std::endl;
}
int main() {
std::thread t(sayHello);
t.join();
return 0;
}
这里,我们定义了一个函数sayHello
,用于输出文本“Hello, World!”。然后,在main
函数中,我们创建了一个线程对象t
,并将sayHello
函数作为线程的入口函数。最后,我们调用了t.join()
,等待线程t
执行完毕。
如何保证线程安全
在多线程程序中,线程之间可能会相互干扰,造成程序出错。为了保证程序的正确性,需要对多线程程序进行保护。以下是一些常用的保护方式:
互斥锁
互斥锁是最常用的一种保护方式,它可以确保在任何时候只有一个线程可以访问被保护的资源。在C++中,可以使用std::mutex
来创建一个互斥锁,如下所示:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex g_mtx;
void printNumber(int num) {
std::lock_guard<std::mutex> lock(g_mtx);
std::cout << num << std::endl;
}
int main() {
std::thread t1(printNumber, 1);
std::thread t2(printNumber, 2);
t1.join();
t2.join();
return 0;
}
在这个示例程序中,我们定义了一个全局的互斥锁g_mtx
,然后在printNumber
函数中,使用std::lock_guard
来保护了输出语句。这样,在任何时候,只有一个线程可以访问输出语句。
条件变量
条件变量是另一种常用的保护方式,它可以在多个线程之间进行通信。在C++中,可以使用std::condition_variable
来创建一个条件变量,如下所示:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex g_mtx;
std::condition_variable g_cv;
bool g_ready = false;
void worker() {
std::unique_lock<std::mutex> lock(g_mtx);
g_ready = true;
std::cout << "Worker is working!" << std::endl;
g_cv.notify_all();
}
int main() {
std::thread t(worker);
std::unique_lock<std::mutex> lock(g_mtx);
while (!g_ready) {
g_cv.wait(lock);
}
std::cout << "Main thread is working!" << std::endl;
t.join();
return 0;
}
在这个示例程序中,我们定义了一个全局的条件变量g_cv
和一个布尔变量g_ready
,然后在worker
函数中,将g_ready
设置为true
,并通过g_cv.notify_all()
来通知等待的线程。在main
函数中,我们使用g_cv.wait(lock)
来等待g_ready
为true
。当g_ready
为true
时,g_cv.wait(lock)
会解除阻塞,然后输出文本“Main thread is working!”。
结束语
以上是一个简单的多线程程序的示例,希望能对你有所帮助。当然,在实际的程序中,多线程的应用远远不止于此,还需要考虑如何合理地分配和管理线程等问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11 并发指南之多线程初探 - Python技术站