基于linuxthreads2.0.1线程如何进行源码分析join.c
发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,基于linuxthreads2.0.1线程如何进行源码分析join.c,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。join.c文件
千家信息网最后更新 2025年02月02日基于linuxthreads2.0.1线程如何进行源码分析join.c
基于linuxthreads2.0.1线程如何进行源码分析join.c,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
join.c文件一共有三个函数,下面我们一个个看一下。
1 pthread_exit
// 线程退出
void pthread_exit(void * retval)
{
// 获取当前线程的结构体
pthread_t self = thread_self();
pthread_t joining;
struct pthread_request request;
/* Reset the cancellation flag to avoid looping if the cleanup handlers
contain cancellation points */
// 设置成0,避免其他函数里判断是cancel状态,然后再调pthread_exit函数
self->p_canceled = 0;
/* Call cleanup functions and destroy the thread-specific data */
// 执行clean节点的函数
__pthread_perform_cleanup();
// 遍历pthread_keys数组,销毁线程中的specifics数据
__pthread_destroy_specifics();
/* Store return value */
// 加锁
acquire(&self->p_spinlock);
// 退出值,可以在join中返回给其他线程
self->p_retval = retval;
/* Say that we've terminated */
// 已终止
self->p_terminated = 1;
/* See if someone is joining on us */
// 判断有没有其他线程在等待该线程退出
joining = self->p_joining;
release(&self->p_spinlock);
/* Restart joining thread if any */
// 唤醒他
if (joining != NULL) restart(joining);
/* If this is the initial thread, block until all threads have terminated.
If another thread calls exit, we'll be terminated from our signal
handler. */
// 如果是主线程退出,通知manage线程,如果是一般线程则直接执行exit退出
if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
request.req_thread = self;
request.req_kind = REQ_MAIN_THREAD_EXIT;
// 写入管道
__libc_write(__pthread_manager_request, (char *)&request, sizeof(request));
// 挂起等待唤醒,全部子线程都退出后了才唤醒主线程,然后主线程也退出,见manager.c的__pthread_manager函数
suspend(self);
}
/* Exit the process (but don't flush stdio streams, and don't run
atexit functions). */
// 线程退出,见操作系统实现
_exit(0);
}
2 pthread_join
// 调用该函数的线程会等待th线程结束
int pthread_join(pthread_t th, void ** thread_return)
{
volatile pthread_t self = thread_self();
struct pthread_request request;
// 不能等待自己结束,否则会死锁,即自己无法结束
if (th == self) return EDEADLK;
acquire(&th->p_spinlock);
/* If detached or already joined, error */
// th线程已经是detach状态,即不是joinable的,或者已经被jion过了
if (th->p_detached || th->p_joining != NULL) {
release(&th->p_spinlock);
return EINVAL;
}
/* If not terminated yet, suspend ourselves. */
// join的线程还在运行,则需要等待
if (! th->p_terminated) {
// 记录谁在join th
th->p_joining = self;
release(&th->p_spinlock);
// 挂起等待唤醒,th退出的时候才会唤醒self线程,见pthread_exit的restart
suspend_with_cancellation(self);
acquire(&th->p_spinlock);
/* This is a cancellation point */
// 取消点
if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
th->p_joining = NULL;
release(&th->p_spinlock);
pthread_exit(PTHREAD_CANCELED);
}
}
/* Get return value */
// 线程已经结束,设置线程的返回值
if (thread_return != NULL) *thread_return = th->p_retval;
release(&th->p_spinlock);
/* Send notification to thread manager */
// 管道的写端,join的线程已经退出,通知manage线程回收退出线程的资源,见REQ_FREE的处理
if (__pthread_manager_request >= 0) {
// 发送th线程已经结束的通知给manager线程,self是发送者
request.req_thread = self;
request.req_kind = REQ_FREE;
request.req_args.free.thread = th;
// 写入管道
__libc_write(__pthread_manager_request,
(char *) &request, sizeof(request));
}
return 0;
}
3 pthread_detach
int pthread_detach(pthread_t th)
{
int terminated;
struct pthread_request request;
acquire(&th->p_spinlock);
/* If already detached, error */
// detach过了
if (th->p_detached) {
release(&th->p_spinlock);
return EINVAL;
}
/* If already joining, don't do anything. */
// 有线程join了该线程,不能detach
if (th->p_joining != NULL) {
release(&th->p_spinlock);
return 0;
}
/* Mark as detached */
// 标记已经detach
th->p_detached = 1;
terminated = th->p_terminated;
release(&th->p_spinlock);
/* If already terminated, notify thread manager to reclaim resources */
// 线程已经退出了,detach的时候,通知manager,__pthread_manager_request是管道写端
if (terminated && __pthread_manager_request >= 0) {
request.req_thread = thread_self();
request.req_kind = REQ_FREE;
request.req_args.free.thread = th;
__libc_write(__pthread_manager_request,
(char *) &request, sizeof(request));
}
return 0;
}
关于基于linuxthreads2.0.1线程如何进行源码分析join.c问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。
线程
函数
管道
分析
问题
源码
时候
更多
状态
帮助
解答
易行
操作系统
简单易行
三个
内容
发送者
小伙
小伙伴
数据
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
最新流行数据库软件
软件开发搞笑节目剧本
互联网科技股票下跌
软件开发课程表手绘
大学生网络安全问题处理
东方京海网络安全监测装置
全国性网络安全
数据库改用户名是什么原因
网络安全与管理有那些方面
咸阳网络安全宣传活动
如何管理上千台服务器
服务器机房建设公司
参加软件开发心得
长沙软件开发专科学校哪个好
联想安全服务器平台
易语言edb数据库操作
微软服务器远程要授权吗
通付盾 网络安全交流
物流管理数据库系统源代码
江苏优质订货软件开发
计算机网络技术专业领军人物
喋血复仇服务器卡不卡
网络安全事故登记表格
如何学软件开发课程
服务器主板用什么牌子的好
北京pdu服务器电源价位
学习计算机网络技术感受
明日之后手游服务器信息
什么是数据库vf
提高软件开发效果