linux 线程笔记

线程与进程关键字对比

创建新流 fork/pthread_create
退出控制流 exit/pthread_exit
获取退出状态 waitpid/pthread_join
在退出时的清理工作 atexit/pthread_cleanup_push
非正常退出 abort/pthread_cancel

创建线程

int pthread_create(线程ID返回值, 线程属性, 任务地址, 任务附加参数)
获取线程ID: pthread_t pthread_self(void)
判断是否同一线程: int pthread_equal(pthread_t tid1, pthread_t tid2)

线程终止

线程退出方式: pthread_exit; 线程正常执行完毕返回; 被同一进程中的其它线程取消
错误退出方式: 调用exit, _exit, _Exit都会使整个进程退出
获取返回值: pthread_join

线程清理

pthread_cleanup_push: 添加一个清理函数, 如果意外退出可以确保资源释放
pthread_cleanup_pop(0): 取消清理函数, 比如主动清理完成时便可以调用pop来取消push的操作
以下三种情况会触发push操作:

  • 调用pthread_exit退出(调用return不会触发)
  • 响应pthread_cancel请求
  • pthread_cleanup_pop(int), int参数为非零时

线程同步

1.互斥量
2.读写锁
3.条件变量

例子

1.创建和退出线程

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
 
void *
thr_fn1(void *arg){
    printf("thread 1 returning 
");
    return((void *)1);
}
 
void *
thr_fn2(void *arg){
    printf("thread 2 exiting
");
    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
",(int)tret);
    err=pthread_join(tid2,&tret);
    if(err != 0){
        perror("pthread_join error");
        return -1;
    }
    printf("thread 2 exit code %d
",(int)tret);
    return 0;
}

2.清理函数

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
 
void cleanup(void *arg){
    printf("in cleanup : %s
",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第四个参数,
//0时会执行pop取消清理函数, 1时以return方式退出不触发清理函数,2时以pthread_exit方式退出触发清理函数
    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
",(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
",++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;
}
原文地址:https://www.cnblogs.com/cfans1993/p/5608848.html