12.2 OS线程绑定
12.2.1 os_linux.cpp
12.2.1.1 create_main_thread
这个函数的入口函数是thread.cpp->set_as_starting_thread()
bool os::create_main_thread(JavaThread* thread) {
// 断言判断,主线程必须是当前线程,否则抛出异常退出
assert(os::Linux::_main_thread == pthread_self(), "should be called inside main thread");
return create_attached_thread(thread);
}
bool os::create_attached_thread(JavaThread* thread) {
#ifdef ASSERT
thread->verify_not_published(); // 验证线程还没发布出去,Threads_lock锁的持有者还是当前线程
#endif
// 创建并分配 OSThread 对象,看`章节12.2.1.1.1`
OSThread* osthread = new OSThread(NULL, NULL);
if (osthread == NULL) {
return false;
}
// Store pthread info into the OSThread
// 内核级的线程唯一id
osthread->set_thread_id(os::Linux::gettid());
// 函数库级的pthread id,也可以称为线程id,每个进程有多个线程,不同的进程之间,线程id可能相同,但是内核级的线程id是唯一的,不会相同
osthread->set_pthread_id(::pthread_self()); // 当前线程的pthread id
// 初始化浮点计算单元
os::Linux::init_thread_fpu_state();
// 初始化线程状态为 RUNNABLE
osthread->set_state(RUNNABLE);
// 将OSThread绑定到JavaThread中
thread->set_osthread(osthread);
if (UseNUMA) {
int lgrp_id = os::numa_get_group_id();
if (lgrp_id != -1) {
thread->set_lgrp_id(lgrp_id);
}
}
if (os::is_primordial_thread()) {
JavaThread *jt = (JavaThread *)thread;
// 获取线程栈的黄页区基址,细节看`章节12.3 线程栈保护区`的介绍
address addr = jt->stack_yellow_zone_base();
assert(addr != NULL, "initialization problem?");
assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
// 扩展线程栈空间(保护区)
osthread->set_expanding_stack();
os::Linux::manually_expand_stack(jt, addr);
osthread->clear_expanding_stack();
}
// 初始化线程的信号屏蔽号
os::Linux::hotspot_sigmask(thread);
return true;
}
12.2.1.1.1 创建OSThread
OSThread::OSThread(OSThreadStartFunc start_proc, void* start_parm) {
pd_initialize(); // 调用函数OSThread::pd_initialize完成os线程的初始化
set_start_proc(start_proc);
set_start_parm(start_parm);
set_interrupted(false);
}
// 这个函数在osThread_linux.cpp源码中
void OSThread::pd_initialize() {
assert(this != NULL, "check");
_thread_id = 0; // 内核级线程id置为0
_pthread_id = 0; // 对应pthread id,用在函数库中
_siginfo = NULL;
_ucontext = NULL;
_expanding_stack = 0;
_alt_sig_stack = NULL;
sigemptyset(&_caller_sigmask); // 将信号集置空
// 线程启动锁定义
_startThread_lock = new Monitor(Mutex::event, "startThread_lock", true);
assert(_startThread_lock !=NULL, "check");
}
后续将通过抖音视频/直播的形式分享技术,由于前期要做一些准备和规划,预计2024年6月开始,欢迎关注,如有需要或问题咨询,也可直接抖音沟通交流。