• Linux 进程与线程二(等待--分离--取消线程)


    int pthread_join(pthread_t thr,void **thr_return);
    pthread_join函数用于挂起当前线程,直至th指定的线程终止为止。
    如果另一个线程返回值不是NULL,则保存在thr_return地址中。
    一个线程所使用的内存资源在应用pthread_join调用之前不会被重新分配,所以对于每个线程必须调用一次pthread_join函数(被分离线程除外)。
    其他线程不能对同一线程再应用pthread_join调用。
    pthread_join函数成功返回0,失败返回错误码
    参数thr_return就是线程th的返回值
    这个函数的应用场景一般是在控制线程中调用,用来等待其他线程返回,跟进程中wait()函数类似。
    一个线程退出后(在控制线程不退出的情况下),该线程所使用的内存资源并没有被释放,需要调用pthread_join()函数释放
    //pthread_join的使用
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <unistd.h>
    #include <errno.h>
    #include <pthread.h>
    
    void * Myfunc(void *arg)
    {
        int *p = (int *) malloc(sizeof(int));
        if (p == NULL)
        {
            printf("分配内存失败!
    ");
            return NULL;
        }
        *p = 5;
        return p;
    }
    
    void * Myfunc2(void *arg)
    {
        int *p = (int *) malloc(sizeof(int));
        if (p == NULL)
        {
            printf("分配内存失败!
    ");
            return NULL;
        }
        *p = 10;
        pthread_exit(p);
    }
    
    int main(int arg, char *args[])
    {
        pthread_t thr1, thr2;
        if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
        {
            printf("create thread is failed ! error message :%s
    ",
                    strerror(errno));
            return -1;
        }
        if (pthread_create(&thr2, NULL, Myfunc2, NULL) != 0)
        {
            printf("create thread is failed ! error message :%s
    ",
                    strerror(errno));
            return -1;
        }
        int *returnnum1 = NULL;
        int *returnnum2 = NULL;
        /*
         pthread_join()函数主要的量大的功能
         1.将控制线程挂起,等待指定的线程返回
         2.释放指定的线程的内存资源(线程正常退出并没有释放自身占用的资源,除非进程退出)
         */
        pthread_join(thr1, (void **) &returnnum1);
        if (returnnum1 != NULL)
        {
            printf("thr1 return number is %d
    ", *returnnum1);
        }
    
        pthread_join(thr2, (void **) &returnnum2);
        if (returnnum2 != NULL)
        {
            printf("thr2 return number is %d
    ", *returnnum2);
        }
        return 0;
    }
    int pthread_detach(pthread_t th);
    pthread_detach函数使线程处于被分离状态。
    对于被分离状态的线程,同时对线程的返回值不感兴趣,可以设置这个线程被分离状态,让系统在线程退出的时候自动回收它所占用的资源。
    一个线程不能自己调用pthread_detach改变自己被分离状态,只能由其他线程调用pthread_detach。
    一旦线程成为可分离线程之后,就不能再使用pthread_joisn()函数了,因为没有意义。
    pthread_detach()成功返回0,失败返回错误码。
    线程处于被分离状态下,控制线程退出,被分离线程也会退出,被分离线程只是不需要使用pthread_join函数来释放内存资源。
    
    可分离线程的使用场景
    1.主线程不需要等待子线程
    2.主线程不关心子线程的返回码
    //pthread_detach的使用
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <unistd.h>
    #include <errno.h>
    #include <pthread.h>
    
    void * Myfunc(void *arg)
    {
        while(1)
        {
            printf("fly with me 
    ");
            sleep(1);
        }
        return NULL;
    }
    
    int main(int arg, char *args[])
    {
        pthread_t thr1;
        if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
        {
            printf("create thread is failed ! error message :%s
    ",
                    strerror(errno));
            return -1;
        }
        pthread_detach(thr1);
        sleep(3);
        printf("main end 
    ");
        return 0;
    }
    int pthread_cancel(pthread_t th);
    pthread_cancel函数允许一个线程取消th指定的另一个线程
    函数成功返回0,失败返回非0.
    //pthread_join的使用
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <unistd.h>
    #include <errno.h>
    #include <pthread.h>
    
    void * Myfunc(void *arg)
    {
        while (1)
        {
            printf("fly with me 
    ");
            sleep(1);
        }
        int *p = malloc(sizeof(int));
        *p = 7;
        return p;
    }
    
    void * Myfunc2(void *arg)
    {
        if(arg==NULL)
        {
            printf("param is not allow NULL!
    ");
            return NULL;
        }
        sleep(5);
        pthread_t thr;
        thr=*(pthread_t *)arg;
        pthread_cancel(thr);
        int *p = malloc(sizeof(int));
        *p = 8;
        return p;
    }
    
    int main(int arg, char *args[])
    {
        pthread_t thr1, thr2;
        if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
        {
            printf("create thread is failed ! error message :%s
    ",
                    strerror(errno));
            return -1;
        }
        if (pthread_create(&thr2, NULL, Myfunc2, &thr1) != 0)
        {
            printf("create thread is failed ! error message :%s
    ",
                    strerror(errno));
            return -1;
        }
        int *numx1 = NULL;
        int *numx2 = NULL;
        pthread_join(thr1, (void **) &numx1);
        pthread_join(thr2, (void **) &numx2);
        /*
         程序报错,线程thr1在执行中被强制取消,返回值numx1并不是NULL
         */
        /*
        if (numx1 != NULL)
        {
            printf("thr1 return code is %d
    ", *numx1);
            free(numx1);
            numx1 = NULL;
        }
        */
        if (numx2 != NULL)
        {
            printf("thr2 return code is %d
    ", *numx2);
            free(numx2);
            numx2 = NULL;
        }
        printf("main end 
    ");
        return 0;
    }
  • 相关阅读:
    【我也不知道是从哪儿来的题】—树(矩阵树定理)
    【我也不知道是从哪儿来的题】—树(矩阵树定理)
    【BJOI2019 Day2】简要题解
    【BJOI2019 Day2】简要题解
    【BJOI2019 Day1】简要题解
    【BJOI2019 Day1】简要题解
    【BZOJ3935】—RBTree(树形dp)
    【BZOJ3935】—RBTree(树形dp)
    2016-8-12
    深入理解web项目的配置文件
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5860548.html
Copyright © 2020-2023  润新知