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

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

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



查看 CPU  信息


cat /proc/cpuinfo

查询结果


processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model       : 60
model name  : Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz
stepping    : 3
microcode   : 0x22
cpu MHz     : 2393.631
cache size  : 6144 KB
physical id : 0
siblings    : 8
core id     : 0
cpu cores   : 4
  • physical id 机器上就安装了几个物理CPU
  • cpu core 记录了每个物理CPU,内部有几个物理核
  • siblings 代表每个物理CPU有多少个逻辑核


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


线程


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


内核线程与用户线程


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


多对一


640.png



一对一

640.png


多对多模型

640.png




JVM 与线程


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


640.png


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
bool os::create_thread(Thread* thread, ThreadType thr_type,
                       size_t req_stack_size) {
  assert(thread->osthread() == NULL, "caller responsible");
  // Allocate the OSThread object (<_<)可能空指针
  OSThread* osthread = new OSThread(NULL, NULL);
  if (osthread == NULL) {
    return false;
  }
  // java_thread
  osthread->set_thread_type(thr_type);
  // Initial state is ALLOCATED but not INITIALIZED
  osthread->set_state(ALLOCATED);
  thread->set_osthread(osthread);
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  // 所以java线程都是分离状态,join也并非用结合状态
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  // -Xss默认1M,Thread没设置stackSize,在Linux-x86默认512K,取最大值
  size_t stack_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_t guard_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_size not aligned");
  int status = 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));
  ThreadState state;
  {
    //欧了,创建线程,函数指针thread_native_entry是重点
    pthread_t tid;
    int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
    pthread_attr_destroy(&attr);
    if (ret != 0) {
      // Need to clean up stuff we've allocated so far
      thread->set_osthread(NULL);
      delete osthread;
      return false;
    }
    // Store pthread info into the OSThread
    osthread->set_pthread_id(tid);
    // 等待thread_native_entry设置osthread为INITIALIZED,或收到终止信号
    {
      Monitor* sync_with_child = osthread->startThread_lock();
      MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
      while ((state = osthread->get_state()) == ALLOCATED) {
        sync_with_child->wait(Mutex::_no_safepoint_check_flag);
      }
    }
  }
    // Aborted due to thread limit being reached
  if (state == ZOMBIE) {
    thread->set_osthread(NULL);
    delete osthread;
    return false;
  }
  // The thread is returned suspended (in state INITIALIZED),
  // and is started higher up in the call chain
  assert(state == INITIALIZED, "race condition");
  return true;
}


相关文章
|
1月前
|
调度 开发者 Python
深入浅出操作系统:进程与线程的奥秘
在数字世界的底层,操作系统扮演着不可或缺的角色。它如同一位高效的管家,协调和控制着计算机硬件与软件资源。本文将拨开迷雾,深入探索操作系统中两个核心概念——进程与线程。我们将从它们的诞生谈起,逐步剖析它们的本质、区别以及如何影响我们日常使用的应用程序性能。通过简单的比喻,我们将理解这些看似抽象的概念,并学会如何在编程实践中高效利用进程与线程。准备好跟随我一起,揭开操作系统的神秘面纱,让我们的代码运行得更加流畅吧!
|
4天前
|
缓存 安全 Linux
Linux系统查看操作系统版本信息、CPU信息、模块信息
在Linux系统中,常用命令可帮助用户查看操作系统版本、CPU信息和模块信息
48 23
|
3月前
线程CPU异常定位分析
【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
94 0
|
2月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
算法 调度 开发者
深入理解操作系统:进程与线程的管理
在数字世界的复杂编织中,操作系统如同一位精明的指挥家,协调着每一个音符的奏响。本篇文章将带领读者穿越操作系统的幕后,探索进程与线程管理的奥秘。从进程的诞生到线程的舞蹈,我们将一起见证这场微观世界的华丽变奏。通过深入浅出的解释和生动的比喻,本文旨在揭示操作系统如何高效地处理多任务,确保系统的稳定性和效率。让我们一起跟随代码的步伐,走进操作系统的内心世界。
|
1月前
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
2月前
|
Java
.如何根据 CPU 核心数设计线程池线程数量
IO 密集型:核心数*2 计算密集型: 核心数+1 为什么加 1?即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保 CPU 的时钟周期不会被浪费。
91 4
|
2月前
|
Linux 调度 C语言
深入理解操作系统:进程和线程的管理
【10月更文挑战第32天】本文旨在通过浅显易懂的语言和实际代码示例,带领读者探索操作系统中进程与线程的奥秘。我们将从基础知识出发,逐步深入到它们在操作系统中的实现和管理机制,最终通过实践加深对这一核心概念的理解。无论你是编程新手还是希望复习相关知识的资深开发者,这篇文章都将为你提供有价值的见解。
|
2月前
深入理解操作系统:进程与线程的管理
【10月更文挑战第30天】操作系统是计算机系统的核心,它负责管理计算机硬件资源,为应用程序提供基础服务。本文将深入探讨操作系统中进程和线程的概念、区别以及它们在资源管理中的作用。通过本文的学习,读者将能够更好地理解操作系统的工作原理,并掌握进程和线程的管理技巧。
49 2
|
2月前
|
调度 Python
深入浅出操作系统:进程与线程的奥秘
【10月更文挑战第28天】在数字世界的幕后,操作系统悄无声息地扮演着关键角色。本文将拨开迷雾,深入探讨操作系统中的两个基本概念——进程和线程。我们将通过生动的比喻和直观的解释,揭示它们之间的差异与联系,并展示如何在实际应用中灵活运用这些知识。准备好了吗?让我们开始这段揭秘之旅!