线程的终止分离

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,一经查实,立即删除!

相关文章

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;则申请者等待直到资源被占有者…

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("…

带环迷宫求最短路径

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

线程的同步与互斥

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

C语言 可变参数

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

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

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

进程间关系和守护进程

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

猴子偷桃问题

http://blog.csdn.net/snow_5288/article/details/52561882 问题描述&#xff1a; /*有一群猴子&#xff0c;去摘了一堆桃子*/ /*商量之后决定每天吃剩余桃子的一半*/ /*当每天大家吃完桃子之后&#xff0c;有个贪心的小猴都会偷偷再吃一个桃子*/ /*按照这样的方式猴子们每天都…

网络相关基础概念

一. 相关基础概念 1.计算机网络的特点 (1)连通性:计算机网络使得上网的用户都能够彼此相连, 好像用户的计算机可以直接相连     (2)资源共享:资源共享可以是信息共享, 软件共享, 硬件共享等等. 由于网络的存在, 使得用户感觉资源就在自己身边 2. 网络 网络是由若干结点和…

linux线程同步(2)-条件变量

https://www.cnblogs.com/yuuyuu/p/5140875.html linux线程同步(2)-条件变量 一.概述 上一篇&#xff0c;介绍了互斥量。条件变量与互斥量不同&#xff0c;互斥量是防止多线程同时访问共享的互斥变量来保护临界区。条件变量…

点对点数据链路层

数据链路层的主要功能将数据转换为相应的比特流使用的信道主要有点对点的信道方式(一对一的方式), 以及广播的信道方式 一. 点对点信道的数据链路层 1. 数据链路和数据帧 链路就是从一个结点连接到相邻结点的一段物理线路(有线或者无线), 期间不准有任何的交换结点, 因此两台…

linux线程同步(1)-互斥量

http://www.cnblogs.com/yuuyuu/p/5140251.html 一.概述 互斥量是线程同步的一种机制&#xff0c;用来保护多线程的共享资源。同一时刻&#xff0c;只允许一个线程对临界区进行访问。 互斥量的工作流程&#xff1a;创建一个…

linux线程同步(3)-读写锁

http://www.cnblogs.com/yuuyuu/p/5143881.html 一.概述 读写锁与互斥量的功能类似&#xff0c;对临界区的共享资源进行保护&#xff01;互斥量一次只让一个线程进入临界区&#xff0c;读写锁比它有更高的并行性。读写锁有…

linux线程同步(5)-屏障

http://www.cnblogs.com/yuuyuu/p/5152560.html 一.概述 barrier(屏障)与互斥量&#xff0c;读写锁&#xff0c;自旋锁不同&#xff0c;它不是用来保护临界区的。相反&#xff0c;它跟条件变量一样&#xff0c;是用来协同多…

Linux多线程与同步

https://www.cnblogs.com/freedomabcd/p/7774743.html 典型的UNIX系统都支持一个进程创建多个线程(thread)。在Linux进程基础中提到&#xff0c;Linux以进程为单位组织操作&#xff0c;Linux中的线程也都基于进程。尽管实现方式有异于其它的UNIX系统&#xff0c;但Linux的多线程…

内存管理(二)

页面置换算法 当发生缺页中断的时候, 系统会在内存中选择一个页面将其换出内存, 而当换出内存的时候如果该页面的内容在内存中发生修改,则必须将该新数据重新写回到磁盘, 然后再将需要换进的数据覆盖掉原来的数据, 而当该数据在内存中没有被修改的时候, 此时就直接用需要换进的…

数据链路层:基本概念

数据链路层的定义 对数据链路层有对上的网络层接口. 对下提供物理层的接口. 定义合适的传输差错率 对传输流进行管理, 以免快速的传输的数据被淹没. 比如发送端发送信号太快, 接受方接受速度较慢, 此时数据链路层就需要提供一定的功能解决这个问题 物理层上传输的基本单元是…

数据链路层: 可靠性传输 六个协议

可靠性传输 1. 差错控制 发送方将数据帧发送, 但是当发送方发送的是一个 1的时候此时接受方却接受的是一个 0. (1)校验 接收方如果帧校验接受到的帧没有问题, 则对发送方发送一个肯定性的确认, 当对这个数据帧进行校验发现这个帧有问题的时候, 此时接受方一种是将这个数据帧…