線程與進(jìn)程關(guān)鍵字對比創(chuàng)建新流 fork/pthread_create
退出控制流 exit/pthread_exit
獲取退出狀態(tài) waitpid/pthread_join
在退出時的清理工作 atexit/pthread_cleanup_push
非正常退出 abort/pthread_cancel
創(chuàng)建線程
int pthread_create(線程ID返回值, 線程屬性, 任務(wù)地址, 任務(wù)附加參數(shù))
獲取線程ID: pthread_t pthread_self(void)
判斷是否同一線程: int pthread_equal(pthread_t tid1, pthread_t tid2)
線程終止
線程退出方式: pthread_exit; 線程正常執(zhí)行完畢返回; 被同一進(jìn)程中的其它線程取消
錯誤退出方式: 調(diào)用exit, _exit, _Exit都會使整個進(jìn)程退出
獲取返回值: pthread_join
線程清理
pthread_cleanup_push: 添加一個清理函數(shù), 如果意外退出可以確保資源釋放
pthread_cleanup_pop(0): 取消清理函數(shù), 比如主動清理完成時便可以調(diào)用pop來取消push的操作
以下三種情況會觸發(fā)push操作:
- 調(diào)用pthread_exit退出(調(diào)用return不會觸發(fā))
- 響應(yīng)pthread_cancel請求
- pthread_cleanup_pop(int), int參數(shù)為非零時
線程同步
1.互斥量
2.讀寫鎖
3.條件變量
例子
1.創(chuàng)建和退出線程
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *
thr_fn1(void *arg){
printf("thread 1 returning \n");
return((void *)1);
}
void *
thr_fn2(void *arg){
printf("thread 2 exiting\n");
pthread_exit((void *)2);
}
int main(){
int err;
pthread_t tid1,tid2;
void *tret;
err=pthread_create(&tid1,NULL,thr_fn1,NULL);
if(err != 0){
perror("pthread_create error");
return -1;
}
err=pthread_create(&tid2,NULL,thr_fn2,NULL);
if(err != 0){
perror("pthread_create error");
return -1;
}
err=pthread_join(tid1,&tret);
if(err != 0){
perror("pthread_join error");
return -1;
}
printf("thread 1 exit code %d\n",(int)tret);
err=pthread_join(tid2,&tret);
if(err != 0){
perror("pthread_join error");
return -1;
}
printf("thread 2 exit code %d\n",(int)tret);
return 0;
}
2.清理函數(shù)
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void cleanup(void *arg){
printf("in cleanup : %s\n",arg);
}
void *
thr_fn1(void *arg){
puts("thread start");
pthread_cleanup_push(cleanup,"the first time");
pthread_cleanup_push(cleanup,"the second time");
if(1==(int)arg)
return((void*)1);
else if(2==(int)arg)
pthread_exit((void*)2);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
return ((void *)0);
}
int main(){
int err;
pthread_t tid1;
void *tret;
//pthread_create的第四個參數(shù),
//0時會執(zhí)行pop取消清理函數(shù),
//1時以return方式退出不觸發(fā)清理函數(shù),
//2時以pthread_exit方式退出觸發(fā)清理函數(shù)
err=pthread_create(&tid1,NULL,thr_fn1,(void *)1);
if(err != 0){
perror("pthread_create error");
return -1;
}
err=pthread_join(tid1,&tret);
if(err != 0){
perror("pthread_join error");
return -1;
}
printf("thread 1 exit code %d\n",(int)tret);
return 0;
}
3.互斥量
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
struct people{
char name[10];
int age;
int count;
pthread_mutex_t lock;
};
struct people * init(){
struct people *man;
if((man=malloc(sizeof(struct people))) != NULL){
man->count=1;
if(pthread_mutex_init(&man->lock,NULL) != 0){
free(man);
return NULL;
}
strcpy(man->name,"wahaha");
man->age=20;
}
return man;
}
void add_count(struct people *man){
pthread_mutex_lock(&man->lock);
puts("----in add_count----");
printf("now count=%d\n",++man->count);
puts("----out add_count----");
pthread_mutex_unlock(&man->lock);
}
void del_count(struct people *man){
pthread_mutex_lock(&man->lock);
if(--man->count == 0){
pthread_mutex_unlock(&man->lock);
pthread_mutex_destroy(&man->lock);
puts("last count to del");
free(man);
}else{
pthread_mutex_unlock(&man->lock);
}
}
void * thr_fn(void *arg){
add_count(arg);
sleep(1);
del_count(arg);
}
int main(){
struct people *man;
man=init();
if(man == NULL){
perror("man init error");
return -1;
}
int err;
pthread_t tid1,tid2;
err=pthread_create(&tid1,NULL,thr_fn,man);
if(err != 0){
perror("pthread_create error");
return -1;
}
err=pthread_create(&tid2,NULL,thr_fn,man);
if(err != 0){
perror("pthread_create error");
return -1;
}
err=pthread_join(tid1,NULL);
if(err != 0){
perror("pthread_join error");
return -1;
}
err=pthread_join(tid2,NULL);
if(err != 0){
perror("pthread_join error");
return -1;
}
del_count(man);
return 0;
}