快捷搜索:  汽车  科技

一个线程可以在几个cpu核心运行:操作系统与CPU是怎么执行线程的

一个线程可以在几个cpu核心运行:操作系统与CPU是怎么执行线程的内核线程就是内核分身,一个没和线程处理一个事务,很少有直接调取内核线程,而是操作用户线程,用户线程与内核线程一对一,多对一,多对多。JVM 提供了 javaThread 类来对 Java 语言的thread Java 语言中创建一个 java.lang.Thread 对象,JVM 会在对象中创建一个 OsThread 来对应Pthread 创建的底层操作系统线程对象。

操作系统与 CPU 是怎么执行线程的?

查看 CPU 信息

cat/proc/cpuinfo

查询结果

processor:0 vendor_id:GenuineIntel cpufamily:6 model:60 modelname:Intel(R)Core(TM)i7-4700MQCPU@2.40GHz stepping:3 microcode:0x22 cpuMHz:2393.631 cachesize:6144KB physicalid:0 siblings:8 coreid:0 cpucores:4

  • physical id 机器上就安装了几个物理CPU
  • cpu core 记录了每个物理CPU 内部有几个物理核
  • siblings 代表每个物理CPU有多少个逻辑核

经常提到 6 核 12 线程,4 核 8 线程是什么意思? 一核会定义处理一个线程,但是为提高效率,经常会将物理虚拟成逻辑处理单元,让一个物理核为2个虚拟核,每个核两个线程。

线程

线程是 CPU 调度的最小单位,程序代码执行的最小单元 进程是资源管理用的 Linux 线程是用户空间的线程,采用的是线程-进程 一对一模型

内核线程与用户线程

内核线程就是内核分身,一个没和线程处理一个事务,很少有直接调取内核线程,而是操作用户线程,用户线程与内核线程一对一,多对一,多对多。

多对一

一个线程可以在几个cpu核心运行:操作系统与CPU是怎么执行线程的(1)

一对一

一个线程可以在几个cpu核心运行:操作系统与CPU是怎么执行线程的(2)

多对对模型

一个线程可以在几个cpu核心运行:操作系统与CPU是怎么执行线程的(3)

JVM 与线程

JVM 提供了 javaThread 类来对 Java 语言的thread Java 语言中创建一个 java.lang.Thread 对象,JVM 会在对象中创建一个 OsThread 来对应Pthread 创建的底层操作系统线程对象。

一个线程可以在几个cpu核心运行:操作系统与CPU是怎么执行线程的(4)

JVM 创建线程源码
  1. JavaThread: 创建线程执行任务,持有java_lang_thread & OSThread对象,维护线程状态运行Thread.run()的地方
  2. OSThread: 由于不同操作系统的状态不一致,所以JVM维护了一套平台线程状态,被JavaThread所持有
  3. java_lang_Thread::ThreadStatus: 即Java线程状态,与java.lang.Thread.state完全一致
  4. OSThread::ThreadState: 2所说的平台线程状态

//os_linux.cpp boolos::create_thread(Thread*thread ThreadTypethr_type size_treq_stack_size){ assert(thread->osthread()==NULL "callerresponsible"); //AllocatetheOSThreadobject(<_<)可能空指针 OSThread*osthread=newOSThread(NULL NULL); if(osthread==NULL){ returnfalse; } //java_thread osthread->set_thread_type(thr_type); //InitialstateisALLOCATEDbutnotINITIALIZED osthread->set_state(ALLOCATED); thread->set_osthread(osthread); pthread_attr_tattr; pthread_attr_init(&attr); //所以java线程都是分离状态,join也并非用结合状态 pthread_attr_setdetachstate(&attr PTHREAD_CREATE_DETACHED); //-Xss默认1M,Thread没设置stackSize,在Linux-x86默认512K,取最大值 size_tstack_size=os::Posix::get_initial_stack_size(thr_type req_stack_size); //这里设置栈警戒缓冲区,默认系统页大小 //原注解的意思是,Linux的NPTL没有完全按照posix标准 //理应guard_size stack_size,且二者大小相等,而不是从stack_size取guard_size作为警戒取 //所以这里模仿实现posix标准 size_tguard_size=os::Linux::default_guard_size(thr_type); if(stack_size<=SIZE_MAX-guard_size){ stack_size =guard_size; } assert(is_aligned(stack_size os::vm_page_size()) "stack_sizenotaligned"); intstatus=pthread_attr_setstacksize(&attr stack_size); assert_status(status==0 status "pthread_attr_setstacksize"); pthread_attr_setguardsize(&attr os::Linux::default_guard_size(thr_type)); ThreadStatestate; { //欧了,创建线程,函数指针thread_native_entry是重点 pthread_ttid; intret=pthread_create(&tid &attr (void*(*)(void*))thread_native_entry thread); pthread_attr_destroy(&attr); if(ret!=0){ //Needtocleanupstuffwe'veallocatedsofar thread->set_osthread(NULL); deleteosthread; returnfalse; } //StorepthreadinfointotheOSThread osthread->set_pthread_id(tid); //等待thread_native_entry设置osthread为INITIALIZED,或收到终止信号 { Monitor*sync_with_child=osthread->startThread_lock(); MutexLockerExml(sync_with_child Mutex::_no_safepoint_check_flag); while((state=osthread->get_state())==ALLOCATED){ sync_with_child->wait(Mutex::_no_safepoint_check_flag); } } } //Abortedduetothreadlimitbeingreached if(state==ZOMBIE){ thread->set_osthread(NULL); deleteosthread; returnfalse; } //Thethreadisreturnedsuspended(instateINITIALIZED) //andisstartedhigherupinthecallchain assert(state==INITIALIZED "racecondition"); returntrue; }欢迎关注公众号:程序员开发者社区

  • https://zhuanlan.zhihu.com/p/103463694

猜您喜欢: