C++14
CMake 3.17
macOS 10.15.5
Clion
#include <iostream>
#include <thread>
void func1(){
std::cout << "func1" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 休眠
}
void func2(){
std::cout << "func2" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 休眠
}
int main() {
std::cout << "Hello, Thread!" << std::endl;
func1();
func2();
return 0;
}
现象:
先打印输出func1两秒后再打印输出func2,再过两秒后退出程序
#include <iostream>
#include <thread>
void func1(){
std::cout << "func1" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 休眠
}
void func2(){
std::cout << "func2" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 休眠
}
int main() {
std::cout << "Hello, Thread!" << std::endl;
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}
现象:
几乎同时打印输出func1 func2, 两秒后退出程序
连接
std::thread t1(func1);
t1.join();
分离
std::thread t1(func1);
t1.detach();
获取线程id
std::thread t1(func1);
std::thread::id t1_id = t1.get_id();
std::cout << "t1 id:" << t1_id << std::endl;
交换两个线程对象所代表的底层句柄(underlying handles)。
std::thread t1(func1);
std::thread t2(func2);
std::cout << "t1 id:" << t1.get_id() << std::endl;
std::cout << "t2 id:" << t2.get_id()<< std::endl;
std::swap(t1, t2);
std::cout << "t1 id:" << t1.get_id() << std::endl;
std::cout << "t2 id:" << t2.get_id()<< std::endl;
t1.join();
t2.join();
# output
Hello, Thread!
t1 id:0x7000069c8000
t2 id:0x700006a4b000
t1 id:0x700006a4b000
t2 id:0x7000069c8000
func1
func2
mutex是用来保证线程同步的,防止不同的线程同时操作同一个共享数据。
#include <iostream>
#include <thread>
#include <mutex>
int count = 10;
std::mutex lock;
void func1(){
while (count>0){
lock.lock();
count--;
std::cout << count << std::endl;
lock.unlock();
}
}
void func2(){
while (count>0){
lock.lock();
count--;
std::cout << count << std::endl;
lock.unlock();
}
}
int main() {
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}
# output
9
8
7
6
5
4
3
2
1
0
-1
但是使用mutex
是不安全的,当一个线程在解锁之前异常退出了,那么其它被阻塞的线程就无法继续下去。
使用lock_guard
则相对安全,它是基于作用域的,能够自解锁,当该对象创建时,它会像m.lock()一样获得互斥锁,当生命周期结束时,它会自动析构(unlock),不会因为某个线程异常退出而影响其他线程
...
while (count>0){
std::lock_guard<std::mutex> lk(lock);
count--;
std::cout << count << std::endl;
}
...
线程的创建和销毁会消耗系统资源,为了避免系统的消耗,加入线程池概念,为的就是创建的线程存到队列中,线程执行结束后,不销毁,等到下一个申请线程时,从队列中取出已有的线程
这里使用GitHub上已经写好的第三方线程池库
GItHub地址: https://github.com/progschj/ThreadPool
#include <iostream>
#include <thread>
#include <mutex>
#include "ThreadPool.h"
void func1(){
std::cout << "func1: " << std::this_thread::get_id() << " :func1" << std::endl; // 打印当前线程id
std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 休眠
}
void func2(){
std::cout << "func2: " << std::this_thread::get_id() << " :func2" << std::endl; // 打印当前线程id
std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 休眠
}
int main() {
ThreadPool pool(4); // 线程池最大线程数为4
pool.enqueue(func1);
pool.enqueue(func1);
pool.enqueue(func2);
pool.enqueue(func2);
pool.enqueue(func2); // 创建5个线程, 只要有两个线程的id相同,就能证明线程池可用
return 0;
}
# output
func1: func1: func2: 0x700002a07000 :func20x700002901000 :func1
func2: 0x700002984000 :func1
0x700002a8a000 :func2
func2: 0x700002901000 :func2
有两个线程的id为0x700002901000
,证明线程池可用
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有