C/C++ Linux/Unix pthread 建立多執行緒用法與範例

本篇 ShengYu 要介紹 C/C++ Linux/Unix pthread 建立多執行緒用法與範例,

  • pthread 建立新 thread 來執行一個函式
  • pthread 建立新 thread 來執行一個函式,且帶入參數
  • pthread 建立新 thread 來執行一個類別函式
  • pthread detach 不等待 thread 執行結束
  • pthread 用陣列建立多個 thread

pthread 建立新 thread 來執行一個函式

pthread 要建立新 thread 的話使用的函式為 pthread_create,
第三個參數為執行緒的函式指標,要注意的是 foo 的函式參數與回傳值類型要符合 pthread_create 的規定,
最後需要使用 pthread_join 來等待 t1 執行完成,這表示主執行緒會停在這一行,直到 t1 thread 執行完成才會往下繼續執行,

cpp-pthread_create.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// g++ cpp-pthread_create.cpp -o a.out -pthread
#include <iostream>
#include <pthread.h>
using namespace std;

void * foo(void *arg) {
cout << "foo\n";
pthread_exit(NULL);
cout << "foo 2\n";
return NULL;
}

int main() {
pthread_t t1;
if (pthread_create(&t1, NULL, foo, NULL) != 0) {
cerr << "Error: pthread_create\n";
}

pthread_join(t1, NULL);

return 0;
}

輸出結果如下,

1
foo

pthread 建立新 thread 來執行一個函式,且帶入參數

這邊示範 pthread 建立新 thread 如何傳遞參數,分別是傳字串跟傳整數,

cpp-pthread_create2.cpp
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
30
31
32
33
// g++ cpp-pthread_create2.cpp -o a.out -pthread
#include <iostream>
#include <pthread.h>
using namespace std;

void * foo(void *arg) {
cout << "foo, " << (char *)arg << "\n";
return NULL;
}

void * bar(void *arg) {
int *n = (int *)arg;
cout << "bar, " << *n << "\n";
return NULL;
}

int main() {
pthread_t t1;
if (pthread_create(&t1, NULL, foo, (void *)"foo thread") != 0) {
cerr << "Error: pthread_create\n";
}

pthread_t t2;
int n = 10;
if (pthread_create(&t2, NULL, bar, &n) != 0) {
cerr << "Error: pthread_create\n";
}

pthread_join(t1, NULL);
pthread_join(t2, NULL);

return 0;
}

輸出結果如下,

1
2
foo, foo thread
bar, 10

pthread 建立新 thread 來執行一個類別函式

這邊示範 pthread_create() 在 class 裡建立 thread,並指定成員函式為 FOO::run()FOO::run() 需要宣告成 static,可參考下面範例的兩種方式寫法,

cpp-pthread_create-class.cpp
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// g++ cpp-pthread_create-class.cpp -o a.out -pthread
#include <iostream>
#include <pthread.h>
using namespace std;

class FOO {
public:
FOO(int id) {
this->id = id;
cout << "FOO id = " << id << "\n";
}

void create_thread() {
if (pthread_create(&t1, NULL, run, this) != 0) {
cerr << "Error: pthread_create\n";
}
}

void join_thread() {
pthread_join(t1, NULL);
}
private:
//static void * run(void *arg);
static void * run(void *arg) {
FOO *self = (FOO *)arg;
cout << "run id = " << self->id << "\n";

return NULL;
}

pthread_t t1;
int id;
};

/*void * FOO::run(void *arg) {
FOO *self = (FOO *)arg;
cout << "run id = " << self->id << "\n";

return NULL;
}*/

int main() {
FOO foo(1);
foo.create_thread();

foo.join_thread();

return 0;
}

結果輸出如下,

1
2
FOO id = 1
run id = 1

跟上例不同,這邊示範 pthread_create() 在 class 外建立 thread,並指定成員函式為 FOO::run()

cpp-pthread_create-class2.cpp
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
30
31
32
33
34
35
36
37
38
39
40
41
// g++ cpp-pthread_create-class2.cpp -o a.out -pthread
#include <iostream>
#include <pthread.h>
using namespace std;

class FOO {
public:
FOO(int id) {
this->id = id;
cout << "FOO id = " << id << "\n";
}

//static void * run(void *arg);
static void * run(void *arg) {
FOO *self = (FOO *)arg;
cout << "run id = " << self->id << "\n";

return NULL;
}
private:
int id;
};

/*void * FOO::run(void *arg) {
FOO *self = (FOO *)arg;
cout << "run id = " << self->id << "\n";

return NULL;
}*/

int main() {
FOO foo(1);
pthread_t t1;
if (pthread_create(&t1, NULL, FOO::run, &foo) != 0) {
cerr << "Error: pthread_create\n";
}

pthread_join(t1, NULL);

return 0;
}

結果輸出同上。

pthread detach 不等待 thread 執行結束

如果主執行緒不想等或是可以不用等待 t1 執行緒的話,
就可以使用 pthread_detach() 來讓 t1 執行緒分離,接著主執行緒就可以繼續執行,t1執行緒也在繼續執行,
也可以在 foo 裡使用 pthread_detach() 使用 pthread_self() 傳入自身的 pthread_t 即可,

cpp-pthread_create-detach.cpp
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
// g++ cpp-pthread_create-detach.cpp -o a.out -pthread
#include <iostream>
#include <pthread.h>
#include <unistd.h> // for sleep
using namespace std;

void * foo(void *arg) {
// pthread_detach(pthread_self());
cout << "foo 1\n";
sleep(1);
cout << "foo 2\n";
//pthread_exit(NULL);
return NULL;
}

int main() {
pthread_t t1;
if (pthread_create(&t1, NULL, foo, NULL) != 0) {
cerr << "Error: pthread_create\n";
}
cout << "main 1\n";
pthread_detach(t1);
cout << "main 2\n";
return 0;
}

輸出結果如下,

1
2
3
main 1
main 2
foo 1

pthread 用陣列建立多個 thread

這邊示範用陣列建立多個 thread,傳入的參數也變成陣列各自獨立,

cpp-pthread_create-array.cpp
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
// g++ cpp-pthread_create-array.cpp -o a.out -pthread
#include <iostream>
#include <pthread.h>
using namespace std;

void * foo(void *arg) {
int n = *(int *)arg;
//cout << "foo, n=" << n << "\n" << endl;
printf("foo, n=%d\n", n);
return NULL;
}

int main() {
pthread_t threads[3];
int args[3];
for (int i = 0; i < 3; i++) {
args[i] = i;
if (pthread_create(&threads[i], NULL, foo, &args[i]) != 0) {
cerr << "Error: pthread_create\n";
}
}

for (int i = 0; i < 3; i++) {
pthread_join(threads[i], NULL);
}

return 0;
}

執行結果如下,

1
2
3
foo, n=1
foo, n=0
foo, n=2

以上就是 C/C++ Linux/Unix pthread 建立多執行緒用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
C/C++ 新手入門教學懶人包
C/C++ Linux pthread_join 用法與範例
C/C++ Linux pthread_exit 用法與範例
C/C++ Linux pthread_attr_setstacksize 設定執行緒堆疊大小用法
C/C++ sleep 用法與範例
C++ std::thread 建立多執行緒用法與範例