1. 程式人生 > >linux學習-執行緒簡介

linux學習-執行緒簡介

執行緒概念 典型的linux系統下面,一個程序看成只有一個執行緒:一個程序在某一時刻只能做一件事情。而加入了多個控制執行緒之後,在某一時刻我們就可以做不止一件事情。 每個執行緒也有一個執行緒ID,用pthread_t資料型別來表示。可以呼叫函式pthread_self來獲得自身的執行緒ID。

#include<pthread.h>
pthread_t  pthread_self(void);
                                             返回值:返回自身的id

執行緒的建立 新增的執行緒可以通過呼叫函式pthread_creat來建立

#include<pthread.h>
int pthread_create(pthread_t *restrict tidp,const thread_attr_t *restrict attr,void *(*start_rtn)(void *),void *reatrict arg);
                返回值:若成功返回0,否則返回錯誤編號

引數tidp:新建立的執行緒ID會被設定成tidp指向的記憶體單元 引數arrt:用於定製各種不同的執行緒屬性,NULL表示預設屬性 引數start_rtn:新建立的執行緒從函式start_rtn的地址開始執行 引數arg:作為引數傳入函式start_rtn,如果需要傳遞的引數在一個以上,需要構建結構體,然後把結構體地址作為引數傳給函式。

一個建立執行緒的例項

#include<stdio.h>
#include<pthread.h>

void *thr_fn(void *arg)                                                //執行緒執行的函式
{
	printf("hello\n");
	return((void *)0);
}

int main()
{
pthread_t tid;
pthread_creat(&tid,NULL,thr_fn,NULL);                    //建立執行緒
printf("ok\n");
sleep(2);                                                //主執行緒掛起,否則可能導致程序結束,新程序不執行
return 0;
}

執行緒的終止 在不終止整個程序的情況下,單個執行緒可以通過3種方式退出 1)執行緒可以簡單的從啟動例程返回 2)執行緒可以被同一程序中的其他執行緒取消 3)執行緒呼叫pthread_exit

#include<pthread.h>
int pthread_exit(void *rval_ptr);

引數rval_ptr:是一個無型別指標,與傳給啟動例程的單個引數相似。如果執行緒簡單地從它的啟動例程返回,rval_ptr就包含返回碼,如果執行緒被取消,由rval_ptr指定的記憶體單元就設定為PTHREAD_CANCELED。 程序中的其他執行緒可以呼叫函式pthread_join來訪問這個指標。當一個執行緒通過函式pthread_exit退出或簡單的返回,程序中其他執行緒可以通過pthread_join函式來獲得該執行緒的退出狀態 。

#include<pthread.h>
int pthread_join(pthread_t thread,void **rval_ptr);
返回值:成功返回0,出錯返回錯誤編碼

執行緒可以通過呼叫函式pthread_cancel來請求取消同一程序中的其他執行緒。

#include<pthread.h>
int pthread_cancel(pthread_t tid);
                                      返回值:成功返回0,失敗返回錯誤編碼

不過需要注意的是,這個函式只是一個請求,並不等待執行緒終止。

執行緒可以安排它退出時需要呼叫的函式,這樣的函式被稱為執行緒清理函式

#include<pthread.h>
void pthread_cleanup_push(void(*rtn)(void *),void *arg);
void pthread_cleanup_pop(int execute);

當執行緒執行以下動作時,呼叫執行緒清理函式rtn 1)呼叫函式pthread_exit, 2) 響應取消請求時, 3) 用非零execute引數呼叫pthread_cleanup_pop時。

#include<stdio.h>
#include<pthread.h>
void cleanup(void *arg)                 //執行緒清理函式
{
	printf("clean up\n")
}

void *thr_fn(void *arg)                  //執行緒啟動函式              
{
    printf("thread start\n");
    pthread_cleanup_push(cleanup,"hello");
    printf("thread push complete\n");
    if(arg)
    	pthread_exit((void *)1);
    pthread_cleanup_pop(0);             //刪除呼叫建立的清理程式
    pthread_exit((void *)1);
 }

int main()
{
void *tret;
pthread_t tid;
pthread_creat(&tid,NULL,thr_fn,(void *)1);
pthread_join(tid,&tret);
ptintf("thread exit code %ld\n",(long)tret);
exit(0)
}

程式執行結果

thread start
thread push complete
clean up
thread exit code 1

執行緒與程序的相似之處

程序函式 執行緒函式 描述
fork pthread_create 建立新的控制流
exit phread_exit 從現有的控制流退出
waitpid pthread_join 從控制流中得到退出狀態
atexit pthread_cleanup_push 註冊在退出控制流時呼叫的函式
getpid pthread_self 獲取控制流的ID
abort pthread_cancel 請求控制流的非正常退出