多线程是编程中常用技术,本人由于长久不用,竟然不小心犯了多线程共同使用主线程地址数据的错误。下面概要的介绍下thread的主要函数,并举例梳理下使用thread参数传输错误的原因。
一、thread基本介绍
C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是<atomic> ,<thread>,<mutex>,<condition_variable>和<future>
<thread>:该头文件主要声明了 std::thread 类。
主要的函数如下:
Member functions
- (constructor)
- Construct thread (public member function )
- get_id
- Get thread id (public member function )
- joinable
- Check if joinable (public member function )
- join
- Join thread (public member function )
其中构造函数:
default (1) | thread() noexcept; |
---|---|
initialization (2) | template <class Fn, class... Args> |
copy [deleted] (3) | thread (const thread&) = delete; |
move (4) | thread (thread&& x) noexcept; |
二、代码
#include<vector>
#include<thread>
#include<iostream>
#include<windows.h>
using namespace std;
void func1(void* para) {
int data = *(int*)para;
cout << para << ":";
cout<< data << endl;
Sleep(20);
delete (int*)para;
}
void func2(void* para) {
int data = *(int*)para;
cout << para << ":";
cout << data << endl;
Sleep(20);
}
int test1() {
vector<std::thread> vth;
for (int i = 0; i < 30; i++) {
int* j = new int(i);
vth.push_back(thread(func1, j));
}
for (auto& th : vth) {
th.join();
}
return 0;
}
int test2() {
vector<std::thread> vth;
for (int i = 0; i < 30; i++) {
int j = i;
vth.push_back(thread(func2, &j));
}
for (auto& th : vth) {
th.join();
}
return 0;
}
void main() {
test1();
cout << "====================" << endl;
test2();
}
其执行结果如下:
test1:
005DBEF0005DC170005E9DF0:005D77E8005E9D30:20005D8AB8:8
005DB8F8:10
:1
005E9FA0:15
005E9C70:17
:005D7818:5
005E9F10:23
005DFB10:7
005EA000:26
005E65A8:9
005DB928:11
005E9E20:14
13
005E9E50:19
005E9D90:22
005DFAE0:6
005E9EB0:27
005E9F40:12
005D7958:3
4
005E9D60:21
005E9FD0:25
005DBB28:2
005E9DC0:24
005E9F70:16
:0
005E9EE0:29
005E9E80:28
005E9CA0:18
test2:
004EF918004EF918004EF918004EF918:9
004EF918:7004EF918:004EF918004EF918:10
004EF918:4
004EF918:16
004EF918:8
:19
004EF918:21
004EF918:26
004EF918:12
004EF918:29
004EF918:16
004EF918:9
004EF918:22
004EF918:27
004EF918:28
004EF918:17
3
004EF918:24
004EF918:28
004EF918:
004EF918:19
004EF918:11
:2
004EF918:25
004EF918:14:21
6
004EF918:13
004EF918:3
:1
test2属于错误试用,thread创建的线程共用了主线程中的数据地址,这样主线程或者任意一个线程对参数j的改变,都会导致多线程其他线程中参数j的变化。
这里thread只有一个简单参数,对于多个子参数组成的结构体参数,需要new生成,然后在新线程中释放即可。