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

void * foo(void *arg) {
cout << "foo\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;
}

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
// 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) {
FOO *self = (FOO *)arg;
cout << "run id = " << self->id << "\n";

return NULL;
}

pthread_t t1;
int id;
};

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

foo.join_thread();

return 0;
}

跟上例不同,這邊示範 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
// 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) {
FOO *self = (FOO *)arg;
cout << "run id = " << self->id << "\n";

return NULL;
}
private:
int id;
};

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 即可,

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
// 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";
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, 1
foo, 0
foo, 2

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