Linux 之 執行緒創建,退出與回收
正文
Linux下的執行緒
Linux下的執行緒是輕量級的行程(LWP),同樣的,執行緒是cpu最小的執行單位,可以多個執行緒共享同一行程的地址空間,但是每個執行緒都擁有自己獨立的PCB,執行緒是堆疊和暫存器的集合,系統以LWP號作為分配資源的依據,可以使用 ps -Lf 行程ID 來查看該行程下的執行緒,
同一行程內執行緒間共享資源:
檔案描述符表,信號處理方式,當前作業目錄,用戶ID,組ID,記憶體地址空間(堆疊除外),
非共享資源:
執行緒ID,信號屏蔽字,用戶堆疊空間,errno變數,行程調度優先級,執行緒內核堆疊(保存執行緒處理器的現場)和堆疊指標,
執行緒的創建
可以使用pthread_create函式來創建執行緒,
函式原型:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
引數:
thread: 執行緒ID
attr: 執行緒屬性
start_routine: 入口函式
arg:初始引數
回傳值:
成功回傳 0 ,失敗回傳錯誤碼
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<pthread.h>
#include<errno.h>
void str_error()
{
const char * str = strerror(errno);
write(STDERR_FILENO,str,sizeof(str));
exit(-1);
}
void *fun(void *arg)
{
printf("thread created successful\n");
return NULL;
}
int main()
{
pthread_t tid;
if(pthread_create(&tid,NULL,fun,NULL) != 0)
{
str_error();
}
sleep(1);
}
輸出:thread created successful
執行緒的退出
return退出
在主控執行緒中return意味著行程的結束,所有執行緒都會被結束;在其他執行緒中return只會結束該執行緒,
exit
exit 意味著結束整個行程,在任何執行緒中呼叫exit都會將整個行程退出,
pthread_exit
函式原型:
#include<pthread.h>
void pthread_exit(void *retval);
在執行緒中呼叫pthread_exit會將呼叫的執行緒退出,并且有又引數retval回傳退出值,這個值由pthread_join函式接收,
pthread_cancel
函式原型:
#include <pthread.h>
int pthread_cancel(pthread_t thread);
可以由任意執行緒呼叫,取消指定ID的執行緒,這個取消并不是實時的,需要在系統呼叫結束的時候才可以被處理,若是一個線s程不產生系統呼叫,使用該函式無法取消執行緒,可以使用pthread_testcancel函式來產生系統呼叫(pthread_testcancel可以產生一次系統呼叫),被取消的執行緒pthread_join接收到退出碼為PTHREAD_CANCELED,
執行緒的回收
和行程相似,執行緒結束后也需要回收(否則會產生僵尸執行緒),但是不同的是行程只能由其父行程回收,執行緒額可以由任意執行緒回收,
pthread_join
函式原型:
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
引數:
thread: 執行緒ID
retval:用于接收執行緒退出狀態
回傳值:
成功回傳 0 ,失敗回傳錯誤碼
pthread_join函式效果等同于行程中的waitpid函式,呼叫后阻塞,等待指定ID的執行緒結束后回傳,
呼叫前提:回收的執行緒屬性必須是joinable,否則呼叫失敗
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<pthread.h>
#include<errno.h>
void str_error()
{
const char * str = strerror(errno);
write(STDERR_FILENO,str,sizeof(str));
exit(-1);
}
void *fun(void *arg)
{
printf("thread[%ld] created successful\n",pthread_self());
int *retval = (int *)malloc(4);
*retval = 1;
pthread_exit((void*)retval);
}
int main()
{
pthread_t tid;
if(pthread_create(&tid,NULL,fun,NULL) != 0)
{
str_error();
}
int *retval = NULL;
pthread_join(tid,(void*)&retval);
printf("thread[%ld] exited successful,exit status = %d\n",tid,*retval);
}
輸出:
thread[140301426747136] created successful
thread[140301426747136] exited successful,exit status = 1
pthread_detach
函式原型:
#include<pthread.h>
int pthread_detach(pthread_t thread);
引數
thread:指定要分離的執行緒ID
回傳值:
成功回傳 0 ,失敗回傳錯誤碼
呼叫前提:分離的執行緒屬性必須是joinable,否則呼叫失敗
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<pthread.h>
#include<errno.h>
void str_error()
{
const char * str = strerror(errno);
write(STDERR_FILENO,str,sizeof(str));
exit(-1);
}
void *fun(void *arg)
{
sleep(2);
printf("thread[%ld] created successful\n",pthread_self());
}
int main()
{
pthread_t tid;
if(pthread_create(&tid,NULL,fun,NULL) != 0)
{
str_error();
}
pthread_detach(tid);
printf("main thread exit\n");
pthread_exit(NULL);
}
輸出:
main thread exit
thread[140412667537152] created successful
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/29716.html
標籤:其他
