网站首页 > 开源技术 正文
使用lscpu,我们可以看到机器有1个物理核,上面有两个core,然后开起来超线程,所以每个core有两个thread。操作系统就可以看到4个核。
我们使用如下简单的代码来看下我们的程序会使用几个CPU。
可以看到输出NumCpu为4,GOMAXPROCS也为4,看起来一起都正常。那么go runtime是用的什么方法来得到可以使用的核数的呢,是使用的类似lscpu或者读取/proc/cpuinfo之类的方法么?
继续看代码,在runtime/debug.go中,可以看到是直接读取的ncpu这个全局变量得到的,而且注释里面很明确的说明了这个值是在进程初始化的时候读取的,后面就不会再变了。
那么ncpu又是在哪儿赋值的呢,这个时候就可以使用我们万能的grep命令了,直接在/d/go/src/runtime目录下面找ncpu赋值的地方。
grep -Er 'ncpu = ' .
能看到好几个文件都有,我们直接看os_linux.go
可以看到是在osinit中进行赋值的,调用了getproccount函数
getproccount使用了sche_getaffinity这个函数,对其输出buf这个值,直接统计里面的为1的bit的个数,有多个少个bit为1,就表示有多少个CPU。
如果对Linux熟悉的同学可能马上就反应过来了,这个sche_getaffinity不是一个系统调用么,用来得到进程的CPU亲和性的。其值反应在/proc/$pid/status的Cpus_allowed里面的。
我们看下这函数的实现,发现其如下,只有一个函数的声明,并没有函数的实现。
在go中,当发现一个函数只有声明函数原型,但是没有函数体的时候,说明这个函数的实现是用go汇编实现的。我们再用grep看下这个函数在哪儿实现的,发现在runtime/sys_linux_amd64.s里面。
其实现如下,注意go的汇编是plan9汇编语言,这个和我们平时看得比较多的GNU汇编语法差别还是挺大的(go语言是自举的,有自己的编译器,汇编器和链接器,所以用自己的汇编语法是完全没有问题的。)
这个汇编就是将pid,len,buf这三个变量依次放到DI,SI,DX三个寄存器中,然后把sched_getaffinity这个系统调用对应的编号放到AX寄存器中,然后调用SYSCALL指令。这个流程就是LINUX里面标准的系统调用流程。完成之后返回码放到AX寄存器,关心的值从buf出来。
到这儿整个逻辑就通了。go得到NumCpu不是当前集群的lscpu输出的个数,而是系统分配给当前进程的CPU个数。那么为什么我们大部分情况下看到的就是当前系统的CPU个数呢?那是因为默认情况下,系统就是让进程可以使用所有CPU的。但是其实我们可以通过cgroup里面的cpuset来让当前进程只可以使用一部分CPU的。
使用 cgcreate -g cpuset:/gocpu 创建一个cpuset类型的cgroup,名字为gocpu
可以看到当前cpuset.cpus为空的,表示没有亲和性,也就是所有的cpu都可以使用。
我们通过如下命令让在gocpu这cgroup里面的进程只能使用0-1这两个cpu,然后让当前的bash进入这个cgroup中
#echo '0' > cpuset.mems
#echo '0-1' > cpuset.cpus
#echo $ > tasks
可以看到当前bash进程只会在0,1两个cpu上执行了。
然后再启动我们的程序,可以看到NumCpu只有2了。因为当前子进程和继承父进程的cpu亲和性。
猜你喜欢
- 2024-10-08 详解Linux系统inode原理--硬链接、软链接、innodb大小和划分等
- 2024-10-08 每天一个Linux命令(1):ls命令(linux ls常用命令)
- 2024-10-08 CentOS系统下PXE服务器的搭建与部署
- 2024-10-08 腾讯面试:linux内存性能优化总结(linux内存性能测试)
- 2024-10-08 MySQL数据库解读之-内置数据库:sys
- 2024-10-08 ORA-09817: Write to audit file failed 磁盘满了导致登陆失败
- 2024-10-08 如何在 U 盘上安装多个操作系统(u盘制作多个系统的安装盘)
- 2024-10-08 通过十个问题助你彻底理解linux epoll工作原理
- 2024-10-08 使用sysctl调优Linux内核(linux内核调试方法总结)
- 2024-10-08 Python 简单实现贪吃蛇小游戏(用python做贪吃蛇)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)