Linux线程创建、销毁、终止与栈清理

554 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。 ​

目录

一、线程的概念

二、线程的创建

三、线程的终止与栈清理

1、线程终止

2、栈的清理

四、线程取消

五、线程分离

六、线程同步


一、线程的概念

线程就是一个正在运行的函数,不同的平台有不同的线程标准,posix 线程是一套标准,而不是实现;

线程标识:pthread_t,不要用%d直接打印,如果想判断线程 id 可以用 pthread_equal 非零表示相等,pthread_self 返回当前线程号;

二、线程的创建

pthread_create(pthread_t*, const pthread_attr_t,void (func)(void), void*) 创建线程

创建失败直接返回 errorno ,线程的调度取决于调度器策略

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>

static void* fun(void *p) {
    printf("create thread : %lu\n", (unsigned long)(pthread_self()));
    pthread_exit(NULL);
}
int main() {
    pthread_t tid;
    puts("Begin!");
    int err = pthread_create(&tid, NULL, fun, NULL);
    if(err) {
        fprintf(stderr, "pthread create failed : %s\n", strerror(err));
        exit(0);
    }
    //sleep(1);
    pthread_join(tid, NULL);
    puts("End!");
    exit(0);
}

三、线程的终止与栈清理

1、线程终止

线程从启动例程返回,返回值就是线程的退出码,线程可以被同一进程中的其他线程取消;

线程退出调用 pthread_exit() 函数。

2、栈的清理

pthread_cleanup_push();

pthread_cleanup_pop();

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
static void cleanup_func(void *p) {
    puts(p);
}
static void* fun(void *p) {
    printf("create thread : %lu\n", (unsigned long)(pthread_self()));
    pthread_cleanup_push(cleanup_func, "cleanup1");  //相当于宏定义,必须成对出现
    pthread_cleanup_push(cleanup_func, "cleanup2");
    pthread_cleanup_push(cleanup_func, "cleanup3");
    puts("push over!");
    
    

    pthread_cleanup_pop(1);
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);

    pthread_exit(NULL);
}
int main() {
    pthread_t tid;
    puts("Begin!");
    int err = pthread_create(&tid, NULL, fun, NULL);
    if(err) {
        fprintf(stderr, "pthread create failed : %s\n", strerror(err));
        exit(0);
    }
    
    //sleep(1);
    pthread_join(tid, NULL);
    puts("End!");
    exit(0);
}

四、线程取消

使用 pthread_cancel() 有两种状态:允许和不允许

允许取消又分为:异步cancel、推迟cancel;

cancel点:posix定义的cancel点,都是可能引发阻塞的系统调用

pthread_setcancelstate():设置是否允许取消

pthread_setcanceltype():设置取消方式

pthread_testcancel():本函数什么都不做,就是一个取消点

五、线程分离

使用 pthread_detach(),线程分离后,主线程不再管负责收尸工作。

六、线程同步

互斥量:

pthread_mutex_init()

pthread_mutex_destory()

pthread_mutex_lock()

pthread_mutex_trylock()

pthread_mutex_unlock()

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#define THREADNUM 20
#define FNAME "/home/thread/temp.out"
#define LINESIZE 1024
static  pthread_mutex_t ptu = PTHREAD_MUTEX_INITIALIZER;
static void* func(void *i) {
    char buf[LINESIZE];
    FILE* fp;
    fp = fopen(FNAME, "r+");
    if (fp == NULL)  {
        perror("fopen()");
        exit(1);
    }
    pthread_mutex_lock(&ptu);
    fgets(buf, LINESIZE, fp);
    //sleep(1);
    fseek(fp, 0, SEEK_SET);
    fprintf(fp, "%d\n", atoi(buf) + 1);
    fclose(fp);
    pthread_mutex_unlock(&ptu);
    pthread_exit(NULL);
}
int main()  {
    pthread_t tid[THREADNUM];
    int err;
    for (int i = 0; i < THREADNUM; i++) {
        err = pthread_create(tid+i, NULL, func, NULL);
        if (err)  {
            fprintf(stderr, "pthread_create() : %s", strerror(err));
            exit(1);
        }
    }
    for (int i = 0; i < THREADNUM; i++) {
        pthread_join(tid[i], NULL);
    }
    pthread_mutex_destroy(&ptu);
    exit(0);
}