C++11多线程编程基础入门

1. C++11 多线程编程介绍

C++11 多线程编程,是指在同一个进程内,有多个线程来执行程序代码。多线程编程的出现,使得程序能够更有效地利用计算机的多核资源,从而提高程序性能。

下面我们来看看在 C++11 中,多线程编程是如何实现的。

2. 线程的创建和启动

2.1 创建线程

在 C++11 中,创建线程可以通过 std::thread 类来实现。std::thread 类是 C++11 标准库中专门用来处理线程的类,我们可以通过 new 运算符来创建这个类的实例。

#include <iostream>

#include <thread>

using namespace std;

void my_thread_func(){

cout << "Hello from thread!" << endl;

}

int main(){

thread my_thread(my_thread_func);

my_thread.join();

return 0;

}

这段代码通过 std::thread 类创建了一个新的线程 my_thread,并调用 my_thread_func 函数来执行线程中的任务。

2.2 启动线程

调用 std::thread 的 start() 函数来启动一个线程非常直观,但是实际上,在 C++11 中并没有这个函数。

如果你曾经接触过线程编程,肯定非常熟悉调用 pthread_create() 函数来启动一个新线程。而在 C++11 中,我们启动线程的方式也与 pthread_create() 类似,可以通过调用线程实例的 join() 函数来启动线程。

join() 函数用来阻塞调用它的线程,直到另一个线程执行结束。在我们的示例程序中,我们调用了主线程的 join() 函数,使其等待 my_thread 线程结束后再继续运行。

3. 线程的同步

在多线程编程中,由于多个线程可以同时访问同一资源,导致数据的不一致性。因此,在进行多线程编程时,就需要考虑如何保证线程之间的数据一致性。

3.1 互斥量

互斥量是一种控制对共享资源访问的机制,可以保证同一时间只有一个线程能够访问共享资源,从而避免了多个线程同时对同一资源进行修改的情况。

#include <iostream>

#include <thread>

#include <mutex>

using namespace std;

mutex mtx;

int count = 0;

void increase_count(){

for(int i=0; i<1000000; i++){

mtx.lock();

count++;

mtx.unlock();

}

}

int main(){

thread t1(increase_count), t2(increase_count);

t1.join();

t2.join();

cout << "Count: " << count << endl;

}

这段代码通过 std::mutex 类来实现互斥锁。在 increase_count 函数中,我们使用 mutex.lock() 函数来获得锁,使用 mutex.unlock() 函数来释放锁。这样就保证了同一时间内只有一个线程能够访问 count 变量,从而避免了数据不一致的情况。

3.2 条件变量

条件变量是一种更高级的同步机制,它允许线程在某个条件达成之前等待,从而避免了线程在等待时消耗 CPU 时间的情况。条件变量通常和互斥量一起使用,在等待条件满足时,线程解锁互斥量,进入等待状态;当条件满足时,线程再次加锁互斥量。

#include <iostream>

#include <thread>

#include <mutex>

#include <condition_variable>

using namespace std;

mutex mtx;

condition_variable cv;

bool ready = false;

void print_number(int num){

unique_lock<mutex> lock(mtx);

while(!ready){

cv.wait(lock);

}

cout << num << endl;

}

int main(){

thread threads[10];

for(int i=0; i<10; i++){

threads[i] = thread(print_number, i);

}

ready = true;

cv.notify_all();

for(int i=0; i<10; i++){

threads[i].join();

}

return 0;

}

这段代码通过 std::condition_variable 类来实现条件变量。在 print_number 函数中,我们通过 cv.wait(lock) 函数来等待条件变量 ready 的值为 true。在主函数中,我们将 ready 的值设为 true,并通过 cv.notify_all() 函数来激活所有等待条件变量的线程。

4. 线程的销毁

在线程运行结束后,需要及时地销毁线程以释放内存资源。

在线程运行结束后,线程实例中存储的线程的状态并没有释放。因此,我们需要显式地销毁线程以释放内存资源。

#include <iostream>

#include <thread>

#include <chrono>

using namespace std;

void my_thread_func(){

cout << "Thread started!" << endl;

this_thread::sleep_for(chrono::seconds(3));

cout << "Thread ended!" << endl;

}

int main(){

thread my_thread(my_thread_func);

cout << "Main thread started!" << endl;

this_thread::sleep_for(chrono::seconds(1));

my_thread.detach();

if(my_thread.joinable()){

my_thread.join();

}

cout << "Main thread ended!" << endl;

return 0;

}

这段代码通过 std::thread 类来创建线程,并通过调用 detach() 函数来分离线程。分离线程的作用是让线程独立地运行,不再依赖于主线程。在主线程结束后,分离的线程仍然继续运行直到其结束。

5. 总结

C++11 多线程编程是一项非常复杂且核心的技术,需要仔细地掌握。本文介绍了 C++11 多线程编程的基础知识,包括线程的创建、启动、同步和销毁。希望通过本文的介绍,能够帮助读者更好地理解 C++11 中的多线程编程。

后端开发标签