日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【Linux系统编程】线程基本操作

發布時間:2024/4/24 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Linux系统编程】线程基本操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

00. 目錄

文章目錄

    • 00. 目錄
    • 01. 線程概述
    • 02. 線程常用函數
      • 2.1 獲取線程號
      • 2.2 線程號比較
      • 2.3 線程創建
      • 2.4 回收線程資源
      • 2.5 線程分離
      • 2.6 線程退出
    • 03. 附錄

01. 線程概述

每個進程都擁有自己的數據段代碼段堆棧段,這就造成進程在進行創建、切換、撤銷操作時,需要較大的系統開銷。為了減少系統開銷,從進程中演化出了線程。為了讓進程完成一定的工作,進程必須至少包含一個線程。線程存在于進程中,共享進程的資源。

每個進程都有一個進程號一樣,每個線程也有一個線程號。進程號在整個系統中是唯一的,但線程號不同,線程號只在它所屬的進程環境中有效。進程號用 pid_t 數據類型表示,是一個非負整數。線程號則用 pthread_t 數據類型來表示,Linux 使用無符號長整數表示。有的系統在實現 pthread_t 的時候,用一個結構體來表示,所以在可移植的操作系統實現不能把它做為整數處理。

02. 線程常用函數

2.1 獲取線程號

#include <pthread.h> pthread_t pthread_self(void);功能:獲取線程號。 參數:無 返回值:調用線程的線程 ID 。

參考代碼:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h>//unsigned long //pthread_t pthread_self(void);int main(void) {//獲取當前線程的線程IDprintf("tid: %lu\n", pthread_self());return 0; }

2.2 線程號比較

#include <pthread.h> int pthread_equal(pthread_t t1, pthread_t t2); 功能:判斷線程號 t1 和 t2 是否相等。為了方便移植,盡量使用函數來比較線程 ID。 參數:t1,t2:待判斷的線程號。 返回值:相等: 非0不相等:0

參考代碼:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h>//unsigned long //pthread_t pthread_self(void);int main(void) {pthread_t tid = 0;tid = pthread_self();//獲取當前線程的線程IDprintf("tid: %lu\n", pthread_self());//比較兩個線程IDprintf("equal: %d\n", pthread_equal(tid, pthread_self()));return 0; }

注意:

線程函數的程序在 pthread 庫中,故鏈接時要加上參數 -lpthread

2.3 線程創建

#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg); Compile and link with -pthread. 功能:創建一個線程。 參數:thread:線程標識符地址。attr:線程屬性結構體地址,通常設置為 NULL。start_routine:線程函數的入口地址。arg:傳給線程函數的參數。 返回值:成功:0失敗:非 0

pthread_create() 創建的線程從指定的回調函數開始運行,該函數運行完后,該線程也就退出了。線程依賴進程存在的,共享進程的資源,如果創建線程的進程結束了,線程也就結束了。

示例一:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h>void *fun(void *arg) {while(1){printf("do work %#x\n", (unsigned long)arg); sleep(1);}return NULL; }int main(void) {int ret = -1;pthread_t tid = -1;//默認的屬性ret = pthread_create(&tid, NULL, fun, (void *)0x88);if (0 != ret){perror("pthread_create"); goto err0;}getchar();return 0; err0:return 1; }

測試結果:

deng@itcast:/mnt/hgfs/LinuxHome/code.bak2/4sys/7th/code$ ./a.out do work 0x88 do work 0x88 do work 0x88 do work 0x88 do work 0x88 do work 0x88 do work 0x88 do work 0x88 do work 0x88 do work 0x88 do work 0x88

2.4 回收線程資源

#include <pthread.h> int pthread_join(pthread_t thread, void **retval);功能:等待線程結束(此函數會阻塞),并回收線程資源,類似進程的 wait() 函數。如果線程已經結束,那么該函數會立即返回。參數:thread:被等待的線程號。retval:用來存儲線程退出狀態的指針的地址。返回值:成功:0失敗:非 0

參考代碼:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h>void *fun(void *arg) {printf("do work %#x\n", (unsigned long)arg); sleep(2);//線程退出pthread_exit((void *)0x88);//return NULL; }int main(void) {int ret = -1;void *retval = NULL;pthread_t tid = -1;//默認的屬性ret = pthread_create(&tid, NULL, fun, (void *)0x88);if (0 != ret){perror("pthread_create"); goto err0;}printf("main thread do thing1\n");printf("main thread do thing2\n");//等待子線程退出 retvalpthread_join(tid, &retval);printf("retval: %#x\n", retval);printf("main thread exit..\n");return 0; err0:return 1; }

執行結果:

deng@itcast:/mnt/hgfs/LinuxHome/code.bak2/4sys/7th/code$ ./a.out main thread do thing1 main thread do thing2 do work 0x88 retval: 0x88 main thread exit.. deng@itcast:/mnt/hgfs/LinuxHome/code.bak2/4sys/7th/code$

創建一個線程后應回收其資源,但使用 pthread_join() 函數會使調用者阻塞,Linux 還提供了非阻塞函數 pthread_detach() 來回收線程的資源。

2.5 線程分離

#include <pthread.h>int pthread_detach(pthread_t thread); 功能:使調用線程與當前進程分離,分離后不代表此線程不依賴與當前進程,線程分離的目的是將線程資源的回收工作交由系統自動來完成,也就是說當被分離的線程結束之后,系統會自動回收它的資源。所以,此函數不會阻塞。 參數:thread:線程號。 返回值:成功:0失敗:非 0

測試代碼:

#include <stdio.h> #include <unistd.h> #include <pthread.h>void *thead(void *arg) {int i;for(i=0; i<5; i++){printf("I am runing\n");sleep(1);}return NULL; }int main(int argc, char *argv[]) {int ret = 0;pthread_t tid;ret = pthread_create(&tid, NULL, thead, NULL);if(ret!=0){perror("pthread_create");}pthread_detach(tid); // 線程分離,不阻塞// 立馬返回,調用失敗int flag = pthread_join(tid, NULL);if(flag != 0){printf("join not working\n");}printf("after join\n");sleep(3);printf("I am leaving\n");return 0; }

測試結果:

deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c -pthread deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out I am runing join not working after join I am runing I am runing I am leaving deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$

注意

調用 pthread_detach() 后再調用 pthread_join() , pthread_join() 會立馬返回,調用失敗。

2.6 線程退出

在進程中我們可以調用 exit() 函數或 _exit() 函數來結束進程,在一個線程中我們可以通過 pthread_exit() 在不終止整個進程的情況下停止它的控制流。

#include <pthread.h> void pthread_exit(void *retval); 功能:退出調用線程。一個進程中的多個線程是共享該進程的數據段,因此,通常線程退出后所占用的資源并不會釋放。 參數:retval:存儲線程退出狀態的指針。 返回值:無

測試代碼:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h>void *fun(void *arg) {printf("do work %#x\n", (unsigned long)arg); sleep(5);//線程退出pthread_exit(NULL);//return NULL; }int main(void) {int ret = -1;pthread_t tid = -1;//默認的屬性ret = pthread_create(&tid, NULL, fun, (void *)0x88);if (0 != ret){perror("pthread_create"); goto err0;}printf("main thread do thing1\n");printf("main thread do thing2\n");//等待子線程退出pthread_join(tid, NULL);printf("main thread exit..\n");return 0; err0:return 1; }

測試結果:

deng@itcast:/mnt/hgfs/LinuxHome/code.bak2/4sys/7th/code$ ./a.out main thread do thing1 main thread do thing2 do work 0x88 main thread exit.. deng@itcast:/mnt/hgfs/LinuxHome/code.bak2/4sys/7th/code$

03. 附錄

總結

以上是生活随笔為你收集整理的【Linux系统编程】线程基本操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。