linux 線程筆記

線程與進(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;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 基本概念 pthread_cancel調(diào)用并不等待線程終止,它只提出請求。線程在取消請求(pthread_canc...
    鐵甲依然在_978f閱讀 8,387評論 0 1
  • 線程 在linux內(nèi)核那一部分我們知道,線程其實就是一種特殊的進(jìn)程,只是他們共享進(jìn)程的文件和內(nèi)存等資源,無論如何對...
    大雄good閱讀 710評論 0 2
  • 線程基礎(chǔ) 線程是進(jìn)程的一個執(zhí)行單元,執(zhí)行一段程序片段,線程共享全局變量;線程的查看可以使用命令或者文件來進(jìn)行查看;...
    秋風(fēng)弄影閱讀 802評論 0 0
  • 一、什么是線程 1、進(jìn)程與線程 進(jìn)程:一個正在執(zhí)行的程序,它是OS資源分配的最小單位/基本單位。 進(jìn)程中的事情需要...
    3e1094b2ef7b閱讀 670評論 0 0
  • 系統(tǒng)編程第四天 今天講的都是線程相關(guān)內(nèi)容,而且這些內(nèi)容不能放在進(jìn)程中使用。個人感覺最大難點(diǎn)還是代碼的實際應(yīng)用,其他...
    雨打梨花閉門寒閱讀 252評論 0 0

友情鏈接更多精彩內(nèi)容