C++ Linux服务器多线程开发 - C++11线程类(1)

多线程

在C++中多线程的实现方法有POSIX与C++11自带库,在本文中将使用Thread方法。

THREAD

导入库

1
2
#include <iostream>
#include <thread>

THREAD多线程函数基础API

1
2
3
4
5
6
7
thread() //默认构造函数
get_id() //获取线程ID
joinable() //判断线程是否可连接
join() //等待线程结束(阻塞函数)
detach() //使线程与当前线程分离
native_handle() //获取线程句柄(需要本地库支持)
swap() //交换两个线程

创建线程函数

1
2
//批量创建线程对象,但是现在它还不会执行线程
std::thread threads[5];

代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <thread>
#include <unistd.h> //Linux系统下的函数库,sleep()需要用到

void thfunc(int n) {
std::cout << "in threadfunction:" << n << std::endl;
}

int main() {
std::thread threads[5];
for (int i = 0; i < 5; i++) {
threads[i] = std::thread(thfunc, i);
//thread(thfunc,i)的意思是创建一个线程对象,并调用thfunc函数,并将i作为参数传递给该函数
}
for (int i = 0; i < 5; i++) {
threads[i].join();
}//等待所有线程执行完毕
std::cout << "所有线程加载完毕!" << std::endl;
sleep(1); //等待1秒,让线程有足够的时间输出
return 0;
}

以上代码会输出如下:

1
2
3
4
5
6
in threadfunction: 0
in threadfunction: 1
in threadfunction: 2
in threadfunction: 3
in threadfunction: 4
所有线程加载完毕!

yield() - 以线程赛跑举例

yield()函数用于线程调度,让出CPU时间片,让其他线程先执行。

代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <thread>
#include <atomic> //原子操作库,保证线程安全

using namespace std;

atomic<bool> ready(false); //定义一个全局原子变量,用于线程同步

void thfunc(int n) {
while (!ready) {
this_thread::yield(); //当ready为false时,让出CPU时间片
}
for (volatile int i = 0; i < 1000000;++i) {}
//执行一些耗时的操作,volatile的意思是避免编译器对这段代码进行优化,确保每次都从内存中读取变量的值
cout << n << ",";
}

int main() {
thread threads[10]; //定义10个线程对象
cout << "10个线程赛跑排名(线程id):" << endl;
for (int i = 0; i < 10; i++) {
threads[i] = thread(thfunc, i); //启动线程并分配id
}
ready = true;
for (auto& th : threads)
th.join(); //等待所有线程执行完毕
cout << endl;
return 0;
}

以上代码会输出如下:

1
2
10个线程赛跑排名(线程id):
4,6,7,8,9,1,5,0,2,3

每次结果可能都不同,因为线程调度是随机的。
但是若出现顺序错乱,则可能是因为远程调试的延迟问题。


C++ Linux服务器多线程开发 - C++11线程类(1)
http://blog.claret.space/2024/03/07/C++ThreadNotes_Thread/
作者
ClaretWheel1481
发布于
2024年3月7日
许可协议