线程的创建及其在内核空间存在的形式详解

本文详细探讨了线程的创建过程,包括pthread_create函数、线程ID与进程地址空间的关系,以及线程栈的分配。重点讨论了线程连接(join)的必要性,解释了为何不连接退出线程会导致资源泄漏。同时,分析了线程退出的几种方式,以及线程栈的默认大小和管理。
摘要由CSDN通过智能技术生成

pthread_create函数

#include <pthread.h>
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*),
void *restrict arg);

pthread_create函数的第一个参数是pthread_t类型的指针,线程
创建成功的话,会将分配的线程ID填入该指针指向的地址。线程的
后续操作将使用该值作为线程的唯一标识。

第二个参数是pthread_attr_t类型,通过该参数可以定制线程的
属性,比如可以指定新建线程栈的大小、调度策略等。如果创建线
程无特殊的要求,该值也可以是NULL,表示采用默认属性。

第三个参数是线程需要执行的函数。创建线程,是为了让线程
执行一定的任务。线程创建成功之后,该线程就会执行start_routine

函数,该函数之于线程,就如同main函数之于主线程。
第四个参数是新建线程执行的start_routine函数的入参。

新建线程如果想要正常工作,则可能需要入参,那么主线程在调用pthread_create的时候,就可以将入参的指针放入第四个参数以传递给新建线程。

如果线程的执行函数start_routine需要很多入参,传递一个指针就能提供足够的信息吗?线程创建者和线程约定一个结构体,创建者便把信息填入该结构体,再讲结构体指针传递给子进程,子进程只要解析就能取出需要的信息。

如果成功,则pthread_create返回0;如果不成功,则pthread_create返回一个非0的错误码。

线程ID及进程地址空间布局

pthread_create函数,会产生一个线程ID,存放在第一个参数指向的地址中。该pthread_t 和 pid 是一回事吗?

不,不是的。

pid属于进程调度的范畴。因为线程是轻量级进程,是操作系统调度器的最小单位,所以需要一个数值来唯一标识该线程。

pthread_create函数产生并记录在了第一个参数指向地址的线程ID中,属于线程库的范畴,线程库的后续操作就是根据该线程ID操作线程的。就Linux目前使用的NPTL实现而言,pthread_t类型的线程ID,本质就是一个进程地址空间上的一个地址。

pthread_t到底是个什么样的数据结构呢?因为POSIX标准并没有限制pthread_t的数据类型,所以该类型取决于具体实现。对于Linux目前使用的NPTL实现而言,pthread_t类型的线程ID,本质就是一个进程地址空间上的一个地址。

地址空间布局如图:
在这里插入图片描述

主线程的栈大小并不是固定的,要在运行时才能确定大小,因此,在栈中不能存在巨大的局部变量,病外编写递归函数时一定要小心,递归不能太深,否则很可能耗尽栈空间。

由于主线程的栈大小并不是固定的,要在运行时才能确定大小,因此,在栈中不能存在巨大的局部变量,另外编写递归函数时一定要小心,递归不能太深,否则很可能耗尽栈空间。

进程地址空间之中,最大的两块地址空间是内存映射区域和堆。堆的起始地址特别低,向上扩展,mmap区域的起始地址特别高向下扩展。

用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值