一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Linux|Centos|Ubuntu|系統進程|Fedora|注冊表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服務器之家 - 服務器系統 - Linux - Linux多線程編程快速入門

Linux多線程編程快速入門

2022-02-27 21:43yqtaowhu Linux

這篇文章主要介紹了Linux多線程編程快速入門,涉及到了線程基本知識,線程標識,線程創建,線程終止,管理線程的終止等相關內容,小編覺得還是挺不錯的,這里分享給大家,需要的朋友可以參考下

本文主要對Linux下的多線程進行一個入門的介紹,雖然是入門,但是十分詳細,希望大家通過本文所述,對Linux多線程編程的概念有一定的了解。具體如下。

1 線程基本知識

進程是資源管理的基本單元,而線程是系統調度的基本單元,線程是操作系統能夠進行調度運算的最小單位,它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以并發多個線程,每條線程并行執行不同的任務。

一個進程在某一個時刻只能做一件事情,有了多個控制線程以后,在程序的設計成在某一個時刻能夠做不止一件事,每個線程處理獨自的任務。

需要注意的是:即使程序運行在單核處理器上,也能夠得到多線程編程模型的好處。處理器的數量并不影響程序結構,所以不管處理器個數多少,程序都可以通過線程得以簡化。

linux操作系統使用符合POSIX線程作為系統標準線程,該POSIX線程標準定義了一整套操作線程的API。

2. 線程標識

與進程有一個ID一樣,每個線程有一個線程ID,所不同的是,進程ID在整個系統中是唯一的,而線程是依附于進程的,其線程ID只有在所屬的進程中才有意義。線程ID用pthread_t表示。

?
1
2
3
//pthread_self直接返回調用線程的ID
include <pthread.h>
pthread_t pthread_self(void);

判斷兩個線程ID的大小是沒有任何意義的,但有時可能需要判斷兩個給定的線程ID是否相等,使用以下接口:

?
1
2
3
//pthread_equal如果t1和t2所指定的線程ID相同,返回0;否則返回非0值。
include <pthread.h>
int pthread_equal(pthread_t t1, pthread_t t2);

3. 線程創建

一個線程的生命周期起始于它被創建的那一刻,創建線程的接口:

?
1
2
3
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);

函數參數:

?
1
2
3
4
thread(輸出參數),由pthread_create在線程創建成功后返回的線程句柄,該句柄在后續操作線程的API中用于標志該新建的線程;
start_routine(輸入參數),新建線程的入口函數;
arg(輸入參數),傳遞給新線程入口函數的參數;
attr(輸入參數),指定新建線程的屬性,如線程棧大小等;如果值為NULL,表示使用系統默認屬性。

函數返回值:

?
1
2
成功,返回0;
失敗,返回相關錯誤碼。

需要注意:

1.主線程,這是一個進程的初始線程,其入口函數為main函數。
2.新線程的運行時機,一個線程被創建之后有可能不會被馬上執行,甚至,在創建它的線程結束后還沒被執行;也有可能新線程在當前線程從pthread_create前就已經在運行,甚至,在pthread_create前從當前線程返回前新線程就已經執行完畢。

程序實例:

?
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
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
 
void printids(const char *s){
 pid_t pid;
 pthread_t tid;
 pid = getpid();
 tid = pthread_self();
 printf("%s, pid %lu tid %lu (0x%lx)\n",s,(unsigned long)pid,(unsigned long)tid,
 (unsigned long)tid);
}
 
void *thread_func(void *arg){
 printids("new thread: ");
 return ((void*)0);
}
int main() {
 int err;
 pthread_t tid;
 err = pthread_create(&tid,NULL,thread_func,NULL);
 if (err != 0) {
  fprintf(stderr,"create thread fail.\n");
 exit(-1);
 }
 printids("main thread:");
 sleep(1);
 return 0;
}

注意上述的程序中,主線程休眠一秒,如果不休眠,則主線程不休眠,則其可能會退出,這樣新線程可能不會被運行,我自己注釋掉sleep函數,發現好多次才能讓新線程輸出。

編譯命令:

?
1
gcc -o thread thread.c -lpthread

運行結果如下:

?
1
2
main thread:, pid 889 tid 139846854309696 (0x7f30a212f740)
new thread: , pid 889 tid 139846845961984 (0x7f30a1939700)

可以看到兩個線程的進程ID是相同的。其共享進程中的資源。

4. 線程終止

線程的終止分兩種形式:被動終止和主動終止

被動終止有兩種方式:

1.線程所在進程終止,任意線程執行exit、_Exit或者_exit函數,都會導致進程終止,從而導致依附于該進程的所有線程終止。
2.其他線程調用pthread_cancel請求取消該線程。

主動終止也有兩種方式:

1.在線程的入口函數中執行return語句,main函數(主線程入口函數)執行return語句會導致進程終止,從而導致依附于該進程的所有線程終止。
2.線程調用pthread_exit函數,main函數(主線程入口函數)調用pthread_exit函數, 主線程終止,但如果該進程內還有其他線程存在,進程會繼續存在,進程內其他線程繼續運行。

線程終止函數:

?
1
2
include <pthread.h>
void pthread_exit(void *retval);

線程調用pthread_exit函數會導致該調用線程終止,并且返回由retval指定的內容。
注意:retval不能指向該線程的棧空間,否則可能成為野指針!

5. 管理線程的終止

5.1 線程的連接

一個線程的終止對于另外一個線程而言是一種異步的事件,有時我們想等待某個ID的線程終止了再去執行某些操作,pthread_join函數為我們提供了這種功能,該功能稱為線程的連接:

?
1
2
include <pthread.h>
int pthread_join(pthread_t thread, void **retval);

參數說明:

?
1
2
thread(輸入參數),指定我們希望等待的線程
retval(輸出參數),我們等待的線程終止時的返回值,就是在線程入口函數中return的值或者調用pthread_exit函數的參數

返回值:

?
1
2
成功時,返回0
錯誤時,返回正數錯誤碼

當線程X連接線程Y時,如果線程Y仍在運行,則線程X會阻塞直到線程Y終止;如果線程Y在被連接之前已經終止了,那么線程X的連接調用會立即返回。

連接線程其實還有另外一層意義,一個線程終止后,如果沒有人對它進行連接,那么該終止線程占用的資源,系統將無法回收,而該終止線程也會成為僵尸線程。因此,當我們去連接某個線程時,其實也是在告訴系統該終止線程的資源可以回收了。

注意:對于一個已經被連接過的線程再次執行連接操作, 將會導致無法預知的行為!

5.2 線程的分離

有時我們并不在乎某個線程是不是已經終止了,我們只是希望如果某個線程終止了,系統能自動回收掉該終止線程所占用的資源。pthread_detach函數為我們提供了這個功能,該功能稱為線程的分離:

?
1
2
#include <pthread.h>
int pthread_detach(pthread_t thread);

默認情況下,一個線程終止了,是需要在被連接后系統才能回收其占有的資源的。如果我們調用pthread_detach函數去分離某個線程,那么該線程終止后系統將自動回收其資源。

?
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
* 文件名: thread_sample1.c
* 描述:演示線程基本操作
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
 
/*子線程1入口函數*/
void *thread_routine1(void *arg)
{
 fprintf(stdout, "thread1: hello world!\n");
 sleep(1);
 /*子線程1在此退出*/
 return NULL;
}
 
/*子線程2入口函數*/
void *thread_routine2(void *arg)
{
 
 fprintf(stdout, "thread2: I'm running...\n");
 pthread_t main_thread = (pthread_t)arg;
 
 /*分離自我,不能再被連接*/
 pthread_detach(pthread_self());
 
 /*判斷主線程ID與子線程2ID是否相等*/
 if (!pthread_equal(main_thread, pthread_self())) {
  fprintf(stdout, "thread2: main thread id is not equal thread2\n");
 }
 
 /*等待主線程終止*/
 pthread_join(main_thread, NULL);
 fprintf(stdout, "thread2: main thread exit!\n");
 
 fprintf(stdout, "thread2: exit!\n");
 fprintf(stdout, "thread2: process exit!\n");
 /*子線程2在此終止,進程退出*/
 pthread_exit(NULL);
}
 
int main(int argc, char *argv[])
{
 
 /*創建子線程1*/
 pthread_t t1;
 if (pthread_create(&t1, NULL, thread_routine1, NULL)!=0) {
  fprintf(stderr, "create thread fail.\n");
  exit(-1);
 }
 /*等待子線程1終止*/
 pthread_join(t1, NULL);
 fprintf(stdout, "main thread: thread1 terminated!\n\n");
 
 /*創建子線程2,并將主線程ID傳遞給子線程2*/
 pthread_t t2;
 if (pthread_create(&t2, NULL, thread_routine2, (void *)pthread_self())!=0) {
  fprintf(stderr, "create thread fail.\n");
  exit(-1);
 }
 
 fprintf(stdout, "main thread: sleeping...\n");
 sleep(3);
 /*主線程使用pthread_exit函數終止,進程繼續存在*/
 fprintf(stdout, "main thread: exit!\n");
 pthread_exit(NULL);
 
 fprintf(stdout, "main thread: never reach here!\n");
 return 0;
}

最終的執行結果如下:

?
1
2
3
4
5
6
7
8
9
10
thread1: hello world!
main thread: thread1 terminated!
 
main thread: sleeping...
thread2: I'm running...
thread2: main thread id is not equal thread2
main thread: exit!
thread2: main thread exit!
thread2: exit!
thread2: process exit!

總結

以上就是本文關于Linux多線程編程快速入門的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://blog.csdn.net/taoyanqi8932/article/details/56288950

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 四虎成人网 | 春意影院午夜爽爽爽免费 | 久久er国产免费精品 | 99国产精品免费观看视频 | 国产香蕉一区二区在线观看 | 日本卡1卡2卡4卡免费 | 成人猫咪maomiav永久网址 | 国产精品日本一区二区三区在线看 | 天天碰夜夜操 | 国产99热99 | 亚欧精品在线观看 | 男男浴室吸乳play | 日日操天天射 | 日韩成人在线影院 | 免费精品国产在线观看 | 91精品国产高清久久久久久91 | 亚洲无线一二三区2021 | 特黄特级高清免费视频毛片 | 国产精品99久久久 | 成版人快猫永久破解版 | 99热久久这里只有精品23 | 亚洲久草| 韩国伦理hd | 西野翔全部作品在线观看 | 日产国产精品亚洲系列 | 狠狠色狠狠色综合系列 | 深夜在线影院 | 欧美日韩高清观看一区二区 | 国产精品久久久久久吹潮 | 波多野结衣xxxxx在线播放 | 色综合精品 | 日麻逼 | 激情另类国内一区二区视频 | 亚洲欧美精品一区二区 | 男女男精品网站免费观看 | 国产黄色大片网站 | 精品蜜臀AV在线天堂 | 色色色色网站 | 91综合在线视频 | 2021国产麻豆剧传媒剧情 | 欧美一区二区三区在线观看免费 |