基于linuxthreads2.0.1线程如何进行源码分析join.c
发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,基于linuxthreads2.0.1线程如何进行源码分析join.c,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。join.c文件
千家信息网最后更新 2024年11月26日基于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安全错误
数据库的锁怎样保障安全
北仑嵌入式软件开发企业
延吉创业软件开发
公司服务器管理
大话服务器版
广州护苗网络安全课
医学四大英文数据库
sw无人管理服务器
盛安网络技术有限公司
软件开发包含哪些阶段
河南好的软件开发口碑推荐
查看服务器上所有svn项目路径
怀旧服服务器大区分布
网络安全专业的学费
网络安全的五层防御体系
南京市教育局网络安全
上海视频安防软件开发多少钱
软件开发工具考题及答案
东易日盛互联网科技家装怎么样
数据库约束意义
云虚拟主机与云服务器
服务器里属于热插拔配件吗
工控数据库安全解决办法
中国免费网站服务器视频教程
软件开发设计实训总结报告
图片怎么存在数据库的
2020级计算机网络技术
大学生网络安全大创申请书
习近平 网络安全观
王新哲网络安全培训
金寨网络安全排名