前言
? ? ? ? 以下:
概述
? ? ? ? 1.基礎
? ? ? ? 2.代碼演示
? ? ? ? 3.練習
????????4.分析題
1.基礎
一、線程基礎概念
-
并發執行原理
-
通過時間片輪轉實現多任務"并行"效果
-
實際為CPU快速切換執行不同線程
-
-
線程 vs 進程
-
線程共享進程地址空間,切換開銷更小
-
進程擁有獨立資源,隔離性更強
-
二、線程操作函數
1. 線程創建
int pthread_create(
??? pthread_t *id,?????? // 線程ID存儲地址
??? const pthread_attr_t *attr,? // 屬性(NULL為默認)
??? void *(*callback)(void*),? // 線程函數
??? void *arg?????????? // 傳遞給線程的參數
);
-
返回值:成功返回0,失敗返回錯誤碼
-
示例:
pthread_t tid;
int ret = pthread_create(&tid, NULL, thread_func, NULL);
2. 線程終止
void pthread_exit(void *retval);? // 線程主動退出
-
注意:
-
與
exit()
不同,僅終止當前線程 -
retval
可被其他線程通過pthread_join()
獲取
-
3. 線程回收
int pthread_join(pthread_t id, void **retval);
-
功能:阻塞調用線程,直到目標線程結束
-
參數:
-
id
:要等待的線程ID -
retval
:接收線程返回值(二級指針)
-
三、線程控制
1. 線程屬性管理
函數 | 功能 |
---|---|
pthread_self() | 獲取當前線程ID |
pthread_detach(id) | 設置線程為分離態(不可join) |
pthread_cancel(id) | 向線程發送取消請求 |
2. 取消狀態控制
// 設置取消狀態
// 設置取消類型?
pthread_setcanceltype(
??? PTHREAD_CANCEL_DEFERRED,? // 延遲取消(默認)
??? PTHREAD_CANCEL_ASYNCHRONOUS, // 立即取消
??? NULL
);
-
延遲取消:只在取消點(如
sleep()
,?printf()
)響應取消請求 -
立即取消:隨時可能被終止(危險)
四、關鍵示例
1. 基礎線程示例
void* print_msg(void *arg) {
??? printf("Thread ID: %lu\n", pthread_self());
??? pthread_exit(NULL);
}
int main() {
??? pthread_t tid;
??? pthread_create(&tid, NULL, print_msg, NULL);
??? pthread_join(tid, NULL);
??? return 0;
}
2. 取消請求處理
void* worker(void *arg) {
??? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
??? pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
??? while(1) {
??????? printf("Working...\n");
??????? sleep(1);? // 取消點
??? }
??? return NULL;
}
五、注意事項
-
分離態線程
-
設置
pthread_detach()
后:-
不能調用
pthread_join()
-
線程結束后自動釋放資源
-
-
-
線程安全
-
共享數據需通過互斥鎖(
pthread_mutex_t
)保護 -
避免使用全局變量
-
-
錯誤處理
-
所有pthread函數返回0表示成功,非0為錯誤碼
-
建議用
strerror(errno)
輸出錯誤信息
-
2.代碼演示
2.1 pthread_create
#include <IO_head.h>
//分支線程
void* callback(void* arg){while(1){printf("division\n");sleep(1);}return NULL;
}int main(int argc,const char* argv[]){pthread_t thread_id;if(pthread_create(&thread_id, NULL, callback, NULL)!=0){printf("error\n");}else{printf("create succeeded\n");}//主線程while(1){printf("main\n");sleep(1);}return 0;
}
ubuntu@ubuntu:~/IO/class3$ cd ~/IO/class4
ubuntu@ubuntu:~/IO/class4$ ./05_thread
create succeeded
main
division
main
division
main
division
2.2
#include <IO_head.h>
//分支線程
void* callback(void* arg){static int a =200;//important*(int**)arg = &a;return NULL;
}int main(int argc,const char* argv[]){pthread_t thread_id;int* p = NULL;if(pthread_create(&thread_id, NULL, callback, &p)!=0){printf("error\n");}else{printf("create succeeded\n");}//主線程sleep(1);printf("%d\n",*p);return 0;
}
ubuntu@ubuntu:~/IO/class4$ ./06_pointer
create succeeded
200
2.3
#include <IO_head.h>
//分支線程
void* callback(void* arg){//分支線程idprintf("division thread id = %ld\n", pthread_self());static int num =200;//importantpthread_exit(&num);return NULL;
}int main(int argc,const char* argv[]){pthread_t thread_id;if(pthread_create(&thread_id, NULL, callback, NULL)!=0){printf("error\n");}else{printf("create succeeded\n");}//主線程//主線程idprintf("main thread id = %ld\n", pthread_self());int* p = NULL;pthread_join(thread_id,(void**)&p);printf("main thread:num = %d\n",*p);return 0;
}
ubuntu@ubuntu:~/IO/class4$ ./07_self_exit_join
create succeeded
main thread id = 139733924939584
division thread id = 139733924935424
main thread:num = 200
3.練習
分段拷貝
#include <IO_head.h>typedef struct message{int ori_des;int new_des;int len;
}message;void RD_WR(int start, int end, int ori_des, int new_des){lseek(ori_des, start, SEEK_SET);lseek(new_des, start, SEEK_SET);char buf;for(int i = start; i<end;++i){read(ori_des, &buf, 1);write(new_des, &buf, 1);}printf("copy succeeded\n");
}void* callback(void* arg){message* mes_p = (message*)arg;RD_WR(mes_p->len/2, mes_p->len, mes_p->ori_des, mes_p->new_des);pthread_exit(NULL);return NULL;
}int main(int argc, const char* argv[]){//文件IO:文件描述符int file_ori_des = open("./01_vfork.c",O_RDONLY);int file_new_des = open("./01_new_vfork.c",O_WRONLY|O_CREAT|O_TRUNC,0777);int len = lseek(file_ori_des,0,SEEK_END);message message_next = {.ori_des = file_ori_des,.new_des = file_new_des,.len = len};pthread_t thread_id;if(pthread_create(&thread_id,NULL,callback,&message_next)!=0){printf("error\n");}else{NULL;}pthread_join(thread_id,NULL);RD_WR(0, len/2, file_ori_des, file_new_des);return 0;
}
4.分析題
4.1解讀代碼:
結果:
...process1
...process
4.2
for(int i=0;i<3;i++)
{fork()printf("-")
}
運行14次
結語
? ? ? ? 以上