Linux系統程式設計(七)執行緒控制
阿新 • • 發佈:2022-04-22
1、執行緒控制
a. pthread_self
獲取執行緒ID
b. pthread_create
#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
pthread_attr_t意為執行緒屬性,比如執行緒優先順序等,pthread_create執行成功返回0
#include <stdio.h> #include <stdlib.h> #include<pthread.h> #include <unistd.h> void* func(void* arg) { printf("thread: pid = %d, tid = %ld\n", getpid(), pthread_self()); return NULL; } int main(int argc, char** argv) { printf("main: pid = %d, tid = %ld\n", getpid(), pthread_self()); pthread_t tid; int ret = pthread_create(&tid, NULL, func, NULL);if(ret != 0) { perror("pthread_create fail"); exit(1); } sleep(1); return 0; }
man page時看到pthread_create編譯時要加上-pthread,所以編譯時用
$ gcc pthread.c -phread -o pthread
迴圈建立多個執行緒時可能出現問題,例子如下:
void* func(void* arg) { printf("thread %d: pid = %d, tid = %ld\n", *(int*)arg,getpid(), pthread_self());return NULL; } int main(int argc, char** argv) { printf("main: pid = %d, tid = %ld\n", getpid(), pthread_self()); pthread_t tid; int i; for(i = 0; i < 5; i++) { int ret = pthread_create(&tid, NULL, func, (void*)&i); // 這步會出現問題! if(ret != 0) { perror("pthread_create fail"); exit(1); } } sleep(5); return 0; }
看到執行結果如下:
main: pid = 21374, tid = 139621297563456 thread 1: pid = 21374, tid = 139621289035520 thread 2: pid = 21374, tid = 139621280642816 thread 5: pid = 21374, tid = 139621255464704 thread 5: pid = 21374, tid = 139621263857408 thread 5: pid = 21374, tid = 139621272250112
傳遞的是i的地址,子執行緒在執行過程中i值發生變化,子執行緒拿到的值就不是想要的值了
c. pthread_exit
退出當前執行緒
void pthread_exit(void *retval);
這裡來看三個返回:
a. return : 返回到呼叫者
b. pthread_exit :退出執行緒,如果將main函式的return拿掉,新增pthread_exit,那麼主執行緒退出,子執行緒依舊在執行
c. exit :退出程序
d. pthread_join
阻塞等待並回收執行緒
int pthread_join(pthread_t thread, void **retval);
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <string.h> struct Thrd_ret{ int n; char str[128]; }; void* func(void* arg) { struct Thrd_ret* ret; ret = malloc(sizeof(struct Thrd_ret)); ret->n = 100; strcpy(ret->str, "Hello Thread"); printf("Thread : pid = %d, tid = %ld\n", getpid(), pthread_self()); return (void*)ret; } int main(int argc, char** argv) { pthread_t tid; int ret = pthread_create(&tid, NULL, func, NULL); if(ret != 0) { fprintf(stderr, "pthread_create fail, error = %s\n", strerror(ret)); exit(1); } struct Thrd_ret* thrd_ret; pthread_join(tid, (void*)&thrd_ret); printf("ret->n = %d, ret->str = %s\n", thrd_ret->n, thrd_ret->str); pthread_exit(NULL); }
e. pthread_cancel
殺死執行緒,需要一個取消點,如果沒有取消點,可以通過pthread_testcancel新增取消點
int pthread_cancel(pthread_t thread);
f. pthread_detach
實現執行緒分離,執行緒結束時不會殘留資源在核心當中,分離出去的執行緒執行結束之後自動回收,不需要pthread_join去回收
2、執行緒屬性
pthread_attr_int
執行緒屬性初始化
pthread_attr_setdetachstate
設定執行緒屬性為分離屬性
pthread_attr_destroy
銷燬執行緒屬性佔用資源
3、執行緒同步