线程的终止分离

1.线程的终止

                这里写图片描述
    注意该函数是针对用户级别的, 其中 retal 必须指向一个全局变量, 或者是一个 malloc 分配的, 因为如果是线程的局部变量, 当该线程退出时, 其他线程不能得到这个变量, 因为线程的局部变量各自私有

2. 现成的取消

                这里写图片描述
    其中thread是线程的 tid

3.线程的等待与分离

    (1)线程的等待
                这里写图片描述
    注意已经退出的线程它的空间并没有被释放, 它所占有的空间仍然在进程内部, 并且进程创建的新的线程不会复用退出线程的空间, 因此对于已经推出的线程而言, 它所占有的空间必须由主线程将其回收. 因为如果主线程不对退出的线程进行空间回收的, 会造成资源泄露.
    上面函数中 thread是线程的tid, 而retval 是一个指针, 这个指针指向一个指针, 它所指向的这个指针指向线程的返回值(对retval进行一次解引用, 可以获取到线程的返回值), 同样成功时返回 0, 失败时返回错误码.. 调用该函数的线程将会被挂起等待, 直到 id 为thread 的线程终止.
    线程退出的几种情况
    1)代码跑完结果正确,
    2)代码跑完结果错误
    线程通过不同方式退出, retval所指向的内容是不同的
    1)如果线程线程是调用了return 终止(主线程不能用, 因为main 函数调用return相当于进程退出), retval 指向线程函数的返回值
    2)如果线程被其他线程调用了 pthread_cancle , 此时 retval 会指向一个常数, PTHREAD_CANCLED, 该常数是被进行了宏定义为 -1
    3)如果该函数是自己调用了 pthread_exit, retval 指向传给pthread_exit 的参数的地址
    4)如果对线程的退出状态不关心, 此时retval可以被设为 NULL
来看一段代码

#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>void* thread1(void* arg)
{printf("I am thread1\n");int* p = (int*)malloc(sizeof(int));*p = 1;return (void*)p;
}void* thread2(void* arg)
{printf("I am thread2\n");int* p = (int*)malloc(sizeof(int));*p = 2;pthread_exit((void*)p);
}void* thread3(void* arg)
{while(1){printf("I am thread3\n");sleep(1);}return NULL;
}
int main()
{pthread_t tid;void* ret;pthread_create(&tid, NULL, thread1, (void*)1);pthread_join(tid, &ret);printf("tid = %x, ret = %d\n", tid, *(int*)ret);pthread_create(&tid, NULL, thread2, NULL);pthread_join(tid, &ret);printf("tid = %x, ret = %d\n", tid, *(int*)ret);pthread_create(&tid, NULL, thread3, NULL);sleep(3);pthread_cancel(tid);pthread_join(tid, &ret);if(ret == PTHREAD_CANCELED){printf("tid = %x, ret = %d\n", tid, PTHREAD_CANCELED);}return 0;
}

                              这里写图片描述
    由上图可以看出, 由于线程的终止方式采用了不同的方式终止, 一次返回值 ret 所指向的单元存放的信息也是不同的.而其中的 tid 是相同的那是因为 pthread_create 是用户级别的调用, 而在用户眼里,这个 tid 就是一个地址
    (2)线程的分离
    默认情况下, 线程是可分离的(线程在退出时必须对其空间进行回收, 否则会造成内存泄露), 因此必须对线程进行等待, 但是当我们不再关心线程的返回值的时候, 此时我们就可以对线程进行分离. 即当线程退出的时候, 我们可以采用一种机制, 告诉操作系统, 该线程就要退出了, 此时, 操作系统便可以在线程退出时自动将该线程的资源释放.其中一个线程可以被别的线程分离, 也可以自己分离自己
                              这里写图片描述
                              这里写图片描述
    其中 pthrea_self 用来获取线程自身的 tid

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>void* thread1(void* arg)
{printf("%s\n", (char*)arg);pthread_detach(pthread_self());return NULL;
}
int main()
{pthread_t thread;int result;void* ret;if(pthread_create(&thread, NULL, thread1, "thread1 is running") != 0){printf("create thtread is failed\n");return 1;}sleep(1);if(pthread_join(thread, NULL) == 0){printf("wait thread is sucessful\n");result = 0;}else{printf("wait thread is failed\n");result = 1;}return result;
}

                              这里写图片描述
    在上图中, 由于线程已经分离, 但是我们还对其进行 join, 此时必定join 失败, 即对一个已经分离的线程不能再进行 join

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UVa10082

【题目描述】 传送门 【题目分析】 同样是一道模拟&#xff0c;但是如何巧妙快速的解决仍然不简单。通过这道题告诉我们对于复杂确定的对应关系我们要灵活运用常量数组。 同时还需要注意的一个小问题就是字符串数组中的"//"指的是转义后的单斜杠&#xff0c;如果只…

C语言中的深拷贝和浅拷贝

http://www.cnblogs.com/zhanggaofeng/p/5421804.html C语言中的深拷贝和浅拷贝 //C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>typedef struct _student{char name[30];char *title;…

死锁的产生和避免

1.死锁产生的四个必要条件 (1)互斥条件&#xff1a;资源是独占的且排他使用&#xff0c;进程互斥使用资源&#xff0c;即任意时刻一个资源只能给一个进程使用&#xff0c;其他进程若申请一个资源&#xff0c;而该资源被另一进程占有时&#xff0c;则申请者等待直到资源被占有者…

UVa401

【题目描述】 传送门 【题目描述】 嘻嘻&#xff0c;自己做直接AC还是比较开心的。当然有一部分原因是之前看书的时候详细看过这个题的代码&#xff0c;但是这已经快一年了&#xff0c;应该说做出这道题凭借的是自己的能力吧。回过身去看了一下书中的代码发现自己写的不算复…

gethostbyname() 函数说明

https://www.cnblogs.com/cxz2009/archive/2010/11/19/1881611.html gethostbyname()函数说明——用域名或主机名获取IP地址 包含头文件#include <netdb.h>#include <sys/socket.h>函数原型struct hostent *gethostbyname(const char *name);这个函数的传入值是域…

求解迷宫最短路径

1. 多通路迷宫初始化 先构建一个多通路迷宫,并且对其初始化 void MazeInitShortPath(Maze* maze) {if(maze NULL){return;}int row 0;int col 0;for(; row < MAX_COL; row){for(col 0; col < MAX_COL; col){maze -> map[row][col] Map[row][col];}printf("…

UVa340

【题目描述】 传送门 【题目分析】 题目理解以后十分简单&#xff0c;但是这题面实在让人自闭&#xff0c;这么简单的题目啦啦啦啦说了那么多&#xff0c;实在是看不懂。&#xff08;幸亏我看了书理解了题目的意思&#xff0c;要不然。。&#xff09;还是要锻炼自己的读题能…

C语言:结构体中一级指针和二级指针的创建与释放示例

http://blog.csdn.net/Bixiwen_liu/article/details/53610952 这几天把C语言巩固了一下&#xff0c;作为一门最基本的编程语言&#xff0c;C语言还是相当基础和非常重要的&#xff0c;个人认为C语言还是很有必要学好吃透的。 今天写的话题是结构体结构体中一级指针和二级指针的…

带环迷宫求最短路径

前面介绍了简单的迷宫求解问题, 今天我们就对带环迷宫求出它的最短路径 1.首先来看一个带环迷宫的简单地图 在这张迷宫地图中,我们规定入口点的位置entry的坐标是 (0, 1), 同时, 我们给入口点传一个非法坐标,作为入口点的前一个位置(-1, -1). 接下来的思路就和上一篇的思路是一…

UVa1583

【题目描述】 传送门 【题目分析】 我以为很简单就写了一个暴力没有想到超时了。应该是T是非常大的所以必须得打表&#xff0c;将所有的结果都储存起来然后直接输出。 以后遇到这种可以一下算出所有结果的多组数据最好还是算出所有的结果然后再输出答案。 【AC代码】 #inc…

C 结构体嵌套一级指针 二级指针 动态分配内存

https://blog.csdn.net/xielinhua88/article/details/51364623 点击打开链接 #define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> //结构体嵌套一级指针 二级指针 动态分配内存 typedef struct _Teacher { int ag…

线程的同步与互斥

1. 互斥量 在Linux 下线程使用的都是局部变量, 而我们知道, 每一个线程都独立拥有自己的一个栈, 而这些局部便令就在栈中,而线程的创建就是为了实现通信, 此时线程之间无法共享这些变量     为了使得线程之间能够共享数据, 一次我们可以创建一个全局变量, 此时线程都在进程…

二级指针与指针数组的关系

http://blog.csdn.net/shuaishuai80/article/details/6129742 #include <stdio.h> void test(char *argv[]); int main(void) { char *argv[3]{{"abcdefg"},{"1234567"},{"q1w2e3r"}}; test(argv); /*调用指针数组…

UVa1584

【题目描述】 传送门 【题目分析】 也是一道简单的模拟题&#xff0c;1A嘿嘿嘿。 再看书发现和书上的做法差不多。 【AC代码】 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<cstd…

cf#582div3 D——暴力

【题目描述】 The only difference between easy and hard versions is the number of elements in the array.You are given an array a consisting of n integers. In one move you can choose any ai and divide it by 2 rounding down (in other words, in one move you c…

C语言 可变参数

http://www.cnblogs.com/zhanggaofeng/p/6434554.html //可变参数 #include <stdio.h> #include <stdlib.h> #include <string.h> //引用头文件 #include <stdarg.h>/* va_list用于声明一个变量&#xff0c;我们知道函数的可变参数列表其实就是一个字符…

UVa1585

【题目描述】 传送门 【题目分析】 氵 【AC代码】 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<cstdlib> #include<set> #include<map> #include<vector>u…

c语言经典算法——查找一个整数数组中第二大数

https://www.cnblogs.com/dootoo/p/4473958.html 题目&#xff1a; 实现一个函数&#xff0c;查找一个整数数组中第二大数。 算法思想&#xff1a; 设置两个变量max1和max2&#xff0c;用来保存最大数和第二大数&#xff0c;然后将数组剩余的数依次与这两个数比较&#xff0c;如…

进程间关系和守护进程

一. 进程组/作业/会话 1.进程组 每一个进程除了有一个进程ID之外, 还属于一个进程组. 进程是一个或多个进程的集合. 通常, 它们与同一个作业向关联, 可以接收来自同一个终端下的各种命令,信号. 每一个进程组都有唯一的进程组 ID. 每一个进程组都可以有一个组长进程. 组长进程的…

UVa1586

【题目描述】 传送门 【题目分析】 氵 【AC代码】 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<cstdlib> #include<set> #include<map> #include<vector> …