Linux:回收循环建立的多个线程

上午我说了循环建立多个线程,因为进程与线程是如此的类似,进程咱们知道要回收,那么线程也天然要回收啦。咱们接着看控制原语: 多线程

线程与共享 函数

线程间共享全局变量! spa

牢记】:线程默认共享数据段、代码段等地址空间,经常使用的是全局变量。而进程不共享全局变量,只能借助mmap。 线程

pthread_exit函数 指针

将单个线程退出 进程

    void pthread_exit(void *retval);    参数:retval表示线程退出状态,一般传NULL 内存

思考:使用exit将指定线程退出,能够吗?                                            【pthrd_exit.c】 string

    结论:线程中,禁止使用exit函数,会致使进程内全部线程所有退出。 it

    在不添加sleep控制输出顺序的状况下。pthread_create在循环中,几乎瞬间建立5个线程,但只有第1个线程有机会输出(或者第2个也有,也可能没有,取决于内核调度)若是第3个线程执行了exit,将整个进程退出了,因此所有线程退出了。 io

    因此,多线程环境中,应尽可能少用,或者不使用exit函数,取而代之使用pthread_exit函数,将单个线程退出。任何线程里exit致使进程退出,其余线程未工做结束,主控线程退出时不能return或exit。

另注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,由于当其它线程获得这个返回指针时线程函数已经退出了。

总结exit、return、pthread_exit各自退出效果。

return:返回到调用者那里去。

pthread_exit():将调用该函数的线程退出

exit: 将进程退出。

pthread_join函数

阻塞等待线程退出,获取线程退出状态        其做用,对应进程中 waitpid() 函数。

    int pthread_join(pthread_t thread, void **retval); 成功:0;失败:错误号

    参数:thread:线程ID (【注意】:不是指针);retval:存储线程结束状态。

    对比记忆:

        进程中:main返回值、exit参数-->int;等待子进程结束 wait 函数参数-->int *

        线程中:线程主函数返回值、pthread_exit-->void *;等待线程结束 pthread_join 函数参数-->void **

参数 retval 非空用法。

调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不一样的方法终止,经过pthread_join获得的终止状态是不一样的,总结以下:

  1. 若是thread线程经过return返回,retval所指向的单元里存放的是thread线程函数的返回值。
  2. 若是thread线程被别的线程调用pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED。
  3. 若是thread线程是本身调用pthread_exit终止的,retval所指向的单元存放的是传给pthread_exit的参数。
  4. 若是对thread线程的终止状态不感兴趣,能够传NULL给retval参数。

上面说的很清楚啦,因此回收线程的代码实现也很简单啦:

#include <stdio.h>

#include <pthread.h>

#include <string.h>

#include <stdlib.h>

typedef struct {

    int x;

    int y;

    char p[128];

}my_func;

void *func(void*arg)

{

    my_func *mf = (my_func*)malloc(sizeof(my_func));

    int i = (int)arg;

    mf->x = i;

    mf->y = i * i;

    strcpy(mf->p, "my lover is dandan.");

    printf("我是第%d个线程,个人线程ID是%lu\n", i + 1, pthread_self());

    pthread_exit(mf);

}

int main(void)

{

    pthread_t pth[5];

    my_func *mf;//这里是指针啊,是指针啊,不是一个实例啊

    for (int i = 0; i != 5; i++)

    {

        pthread_create((pth + i), NULL, func, (void*)i);

        if (!pthread_join(pth[i], (void**)&mf))

        {

            printf("回收线程成功!线程ID:%lu。\n", pth[i]);

            printf("my_func中的x = %d, y = %d, p = %s。\n\n", mf->x, mf->y, mf->p);

        }

        else

            printf("失败!\n");

    }

    return 0;

}

主要是各类转化要注意,还有的是:my_func *mf;//这里是指针啊,是指针啊,不是一个实例啊         这句话很重要啊,我就说为何个人mf输出像是没有通过初始化和赋值操做的。还有,不用担忧我没有free而形成内存泄漏,pthread_exit函数是把这些考虑好了的。还有个人pthread_exit是传参数进去的,主要是想获取一下线程退出的状态。是否是和wait很相似?

相关文章
相关标签/搜索