当前位置:首页 » 操作系统 » linux线程cpu

linux线程cpu

发布时间: 2023-06-03 10:17:23

1. linux单进程如何实现多核cpu多线程分配

linux下的单进程多线程的程序,要实现每个线程平均分配到多核cpu,主要有2个方法


1:利用linux系统自己的线程切换机制,linux有一个服务叫做irqbalance,这个服务是linux系统自带的,默认会启动,这个服务的作用就是把多线程平均分配到CPU的每个核上面,只要这个服务不停止,多线程分配就可以自己实现。但是要注意,如果线程函数内部的有某个循环,且该循环内没有任何系统调用的话,可能会导致这个线程的CPU时间无法被切换出去。也就是占满CPU现象,此时加个系统调用,例如sleep,线程所占的CPU时间就可以切换出去了。


2:利用pthread库自带的线程亲和性设置函数,来设置线程在某个CPU核心上跑,这个需要在程序内部实现。同时注意不要和进程亲和性设置搞混淆了

intpthread_setaffinity_np(pthread_tthread,size_tcpusetsize,
constcpu_set_t*cpuset);
intpthread_getaffinity_np(pthread_tthread,size_tcpusetsize,
cpu_set_t*cpuset);
从函数名以及参数名都很明了,唯一需要点解释下的可能就是cpu_set_t这个结构体了。这个结构体的理解类似于select中的fd_set,可以理解为cpu集,也是通过约定好的宏来进行清除、设置以及判断:
//初始化,设为空
voidCPU_ZERO(cpu_set_t*set);
//将某个cpu加入cpu集中
voidCPU_SET(intcpu,cpu_set_t*set);
//将某个cpu从cpu集中移出
voidCPU_CLR(intcpu,cpu_set_t*set);
//判断某个cpu是否已在cpu集中设置了
intCPU_ISSET(intcpu,constcpu_set_t*set);

2. linux查看线程占用cpu

top命令是最方便的,想看CPU列的话直接按字母 c 就会以cpu的使用高低来排列。 其实就每一列的第一个字母,如果想按cpu排列就按c ,按内存排列就按m。 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND top [-] [d delay] [q] [c] [s] [S] [i] d 指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之。 q 该选项将使top没有任何延迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行。 S 指定累计模式。 s 使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险。 i 使top不显示任何闲置或者僵死进程。 c 显示整个命令行而不只是显示命令名但是无法显示每个线程的 cpu 利用率情况, 这时就可能出现这种情况,总的 cpu 利用率中 user 或 system 很高,但是用进程的 cpu 占用率进行排序时,没有进程的 user 或 system 与之对应。 可以用下面的命令将 cpu 占用率高的线程找出来: 这个命令首先指定参数'H',显示线程相关的信息,格式输出中包含:user,pid,ppid,tid,time,%cpu,cmd,然后再用%cpu字段进行排序。这样就可以找到占用处理器的线程了。

3. linux下把进程/线程绑定到特定cpu核上运行

你那个是系统下把CPU的核说钉在五河以下是比较好的,因为吧和内心压力非常大,发热量非常大。

4. Linux系统上如何查看进程(线程)所运行的CPU

  • 使用top命令,具体用法是 top -H,加上这个选项,top的每一行就不是显示一个进程,而是一个线程。

  • 使用ps命令,具体用法是 ps -xH,这样可以查看所有存在的线程,也可以使用grep作进一步的过滤。

  • 使用ps命令,具体用法是 ps -mq PID,这样可以看到指定的进程产生的线程数目。

  • 更进一步,其实一些系统监控工具,在本质上也是读取的系统产生的文件罢了。

5. 如何查看linux服务器的cpu数量,内核数,和cpu线程数

lscpu命令,查看的是cpu的统计信息.
blue@blue-pc:~$ lscpu
Architecture: i686 #cpu架构
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian #小尾序
CPU(s): 4 #总共有4核
On-line CPU(s) list: 0-3
Thread(s) per core: 1 #每个cpu核,只能支持一个线程,即不支持超线程
Core(s) per socket: 4 #每个cpu,有4个核
Socket(s): 1 #总共有1一个cpu
Vendor ID: GenuineIntel #cpu产商 intel
CPU family: 6
Model: 42
Stepping: 7
CPU MHz: 1600.000
BogoMIPS: 5986.12
Virtualization: VT-x #支持cpu虚拟化技术
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 6144K

查看/proc/cpuinfo,可以知道每个cpu信息,如每个CPU的型号,主频等。
#cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2320 CPU @ 3.00GHz
.....
上面输出的是第一个cpu部分信息,还有3个cpu信息省略了。

内存
概要查看内存情况
free -m
total used free shared buffers cached
Mem: 3926 3651 274 0 12 404
-/+ buffers/cache: 3235 691
Swap: 9536 31 9505
这里的单位是MB,总共的内存是3926MB。

查看内存详细使用
# cat /proc/meminfo
MemTotal: 4020868 kB
MemFree: 230884 kB
Buffers: 7600 kB
Cached: 454772 kB
SwapCached: 836 kB
.....

查看内存硬件信息
dmidecode -t memory
# dmidecode 2.11
SMBIOS 2.7 present.
Handle 0x0008, DMI type 16, 23 bytes
Physical Memory Array
Location: System Board Or Motherboard
....
Maximum Capacity: 32 GB
....
Handle 0x000A, DMI type 17, 34 bytes
....
Memory Device
Array Handle: 0x0008
Error Information Handle: Not Provided
Total Width: 64 bits
Data Width: 64 bits
Size: 4096 MB
.....
我的主板有4个槽位,只用了一个槽位,上面插了一条4096MB的内存。

磁盘
查看硬盘和分区分布
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 465.8G 0 disk
├—sda1 8:1 0 1G 0 part /boot
├—sda2 8:2 0 9.3G 0 part [SWAP]
├—sda3 8:3 0 74.5G 0 part /
├—sda4 8:4 0 1K 0 part
├—sda5 8:5 0 111.8G 0 part /home
└—sda6 8:6 0 269.2G 0 part
显示很直观

如果要看硬盘和分区的详细信息
# fdisk -l
Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x00023728
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 2148351 1073152 83 Linux
/dev/sda2 2148352 21680127 9765888 82 Linux swap / Solaris
/dev/sda3 21680128 177930239 78125056 83 Linux
/dev/sda4 177932286 976771071 399419393 5 Extended/dev/sda5 177932288 412305407 117186560 83 Linux
/dev/sda6 412307456 976771071 282231808 83 Linux

网卡
查看网卡硬件信息
# lspci | grep -i 'eth'
02:00.0 Ethernet controller: Realtek Semiconctor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 06)

查看系统的所有网络接口
# ifconfig -a
eth0 Link encap:以太网 硬件地址 b8:97:5a:17:b3:8f
.....
lo Link encap:本地环回
.....
或者是
ip link show
1: lo: <LOOPBACK> mtu 16436 qdisc noqueue state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether b8:97:5a:17:b3:8f brd ff:ff:ff:ff:ff:ff

如果要查看某个网络接口的详细信息,例如eth0的详细参数和指标
# ethtool eth0
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full #支持千兆半双工,全双工模式
Supported pause frame use: No
Supports auto-negotiation: Yes #支持自适应模式,一般都支持
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes #默认使用自适应模式
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
.....
Speed: 100Mb/s #现在网卡的速度是100Mb,网卡使用自适应模式,所以推测路由是100Mb,导致网卡从支 持千兆,变成要支持百兆
Duplex: Full #全双工
.....
Link detected: yes #表示有网线连接,和路由是通的

其他
查看pci信息,即主板所有硬件槽信息。
lspci
00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family DRAM Controller (rev 09) #主板芯片
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller (rev 09) #显卡
00:14.0 USB controller: Intel Corporation Panther Point USB xHCI Host Controller (rev 04) #usb控制器
00:16.0 Communication controller: Intel Corporation Panther Point MEI Controller #1 (rev 04)
00:1a.0 USB controller: Intel Corporation Panther Point USB Enhanced Host Controller #2 (rev 04)
00:1b.0 Audio device: Intel Corporation Panther Point High Definition Audio Controller (rev 04) #声卡
00:1c.0 PCI bridge: Intel Corporation Panther Point PCI Express Root Port 1 (rev c4) #pci 插槽
00:1c.2 PCI bridge: Intel Corporation Panther Point PCI Express Root Port 3 (rev c4)
00:1c.3 PCI bridge: Intel Corporation Panther Point PCI Express Root Port 4 (rev c4)
00:1d.0 USB controller: Intel Corporation Panther Point USB Enhanced Host Controller #1 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Panther Point LPC Controller (rev 04)
00:1f.2 IDE interface: Intel Corporation Panther Point 4 port SATA Controller [IDE mode] (rev 04) #硬盘接口
00:1f.3 SMBus: Intel Corporation Panther Point SMBus Controller (rev 04)
00:1f.5 IDE interface: Intel Corporation Panther Point 2 port SATA Controller [IDE mode] (rev 04) #硬盘接口
02:00.0 Ethernet controller: Realtek Semiconctor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 06) #网卡
03:00.0 PCI bridge: Integrated Technology Express, Inc. Device 8893 (rev 41)
如果要更详细的信息:lspci -v 或者 lspci -vv
如果要看设备树:lscpi -t

查看bios信息
# dmidecode -t bios
......
BIOS Information
Vendor: American Megatrends Inc.
Version: 4.6.5
Release Date: 04/25/2012
.......
BIOS Revision: 4.6
......
dmidecode以一种可读的方式mp出机器的DMI(Desktop Management Interface)信息。这些信息包括了硬件以及BIOS,既可以得到当前的配置,也可以得到系统支持的最大配置,比如说支持的最大内存数等。
如果要查看所有有用信息
dmidecode -q
以上是linux查看硬件信息的所有命令,可以查看CPU、硬盘、网卡、磁盘等硬件的信息。

6. linux怎么查看线程cpu

可以用下面的命令将 cpu 占用率高的线程找出来:
ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu

这个命令首先指定参数'H',显示线程相关的信息,格式输出中包含:user,pid,ppid,tid,time,%cpu,cmd,然后再用%cpu字段进行排序。这样就可以找到占用处理器的线程了。

直接使用 ps Hh -eo pid,tid,pcpu | sort -nk3 |tail 获取对于的进程号和线程号,然后跳转到3.
查看哪个进程线程占用cpu过高; top / ps -aux, 获得进程号
确定哪个线程占用cpu过高,进入进程号的目录:/proc/pid/task,
执行:grep SleepAVG **/status | sort -k2,2 | head, 确定cpu占用较高的线程号。
使用kill -3 pid 会打印线程堆栈的情况

在 Linux 下 top 工具可以显示 cpu 的平均利用率(user,nice,system,idle,iowait,irq,softirq,etc.),可以显示每个 cpu 的利用率。但是无法显示每个线程的 cpu 利用率情况,这时就可能出现这种情况,总的 cpu 利用率中 user 或 system 很高,但是用进程的 cpu 占用率进行排序时,没有进程的 user 或 system 与之对应。

7. Linux 进程、线程和CPU的关系,cpu亲和性

1、物理CPU数:机器主板上实际插入的cpu数量,比如说你的主板上安装了一块8核CPU,那么物理CPU个数就是1个,所以物理CPU个数就是主板上安装的CPU个数。

2、物理CPU核数:单个物理CPU上面有多个核,物理CPU核数=物理CPU数✖️单个物理CPU的核
3、逻辑CPU核数:一般情况,我们认为一颗CPU可以有多个核,加上intel的超线程技术(HT), 可以在逻辑上再分一倍数量的CPU core出来。逻辑CPU核数=物理CPU数✖️单个物理CPU的核*2
4、超线程技术(Hyper-Threading):就是利用特殊的硬件指令,把两个逻辑CPU模拟成两个物理CPU,实现多核多线程。我们常听到的双核四线程/四核八线程指的就是支持超线程技术的CPU。

1、并行:两件(多件)事情在同一时刻一起发生。
2、并发:两件(多件)事情在同一时刻只能有一个发生,由于CPU快速切换,从而给人的感觉是同时进行。
3、进程和线程
进程是资源分配的最小单位,一个程序有至少一个进程。线程是程序执行的最小单位。一个进程有至少一个线程。
线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
4、单核多线程:单核CPU上运行多线程, 同一时刻只有一个线程在跑,系统进行线程切换,系统给每个线程分配时间片来执行,看起来就像是同时在跑, 但实际上是每个线程跑一点点就换到其它线程继续跑。
5、多核多线程:每个核上各自运行线程,同一时刻可以有多个线程同时在跑。

1、对于单核:多线程和多进程的多任务是在单cpu交替执行(时间片轮转调度,优先级调度等),属于并发
2、对于多核:同一个时间多个进程运行在不同的CPU核上,或者是同一个时间多个线程能分布在不同的CPU核上(线程数小于内核数),属于并行。
3、上下文切换:上下文切换指的是内核(操作系统的核心)在CPU上对进程或者线程进行切换。上下文切换过程中的信息被保存在进程控制块(PCB-Process Control Block)中。PCB又被称作切换帧(SwitchFrame)。上下文切换的信息会一直被保存在CPU的内存中,直到被再次使用。

CPU 亲和性(affinity)就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。这样可以减少上下文切换的次数,提高程序运行性能。可分为:自然亲和性和硬亲和性
1、自然亲和性:就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,Linux 内核进程调度器天生就具有被称为 软 CPU 亲和性(affinity) 的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。Linux调度器缺省就支持自然CPU亲和性(natural CPU affinity): 调度器会试图保持进程在相同的CPU上运行。
2、硬亲和性:简单来说就是利用linux内核提供给用户的API,强行将进程或者线程绑定到某一个指定的cpu核运行。Linux硬亲和性指定API:taskset .

taskset [options] mask command [arg]...
taskset [options] -p [mask] pid

taskset 命令用于设置或者获取一直指定的 PID 对于 CPU 核的运行依赖关系。也可以用 taskset 启动一个命令,直接设置它的 CPU 核的运行依赖关系。

CPU 核依赖关系是指,命令会被在指定的 CPU 核中运行,而不会再其他 CPU 核中运行的一种调度关系。需要说明的是,在正常情况下,为了系统性能的原因,调度器会尽可能的在一个 CPU 核中维持一个进程的执行。强制指定特殊的 CPU 核依赖关系对于特殊的应用是有意义的
CPU 核的定义采用位定义的方式进行,最低位代表 CPU0,然后依次排序。这种位定义可以超过系统实际的 CPU 总数,并不会存在问题。通过命令获得的这种 CPU 位标记,只会包含系统实际 CPU 的数目。如果设定的位标记少于系统 CPU 的实际数目,那么命令会产生一个错误。当然这种给定的和获取的位标记采用 16 进制标识。
0x00000001
代表 #0 CPU
0x00000003
代表 #0 和 #1 CPU
0xFFFFFFFF
代表 #0 到 #31 CPU

-p, --pid
对一个现有的进程进行操作,而不是启动一个新的进程
-c, --cpu-list
使用 CPU 编号替代位标记,这可以是一个列表,列表中可以使用逗号分隔,或者使用 "-" 进行范围标记,例如:0,5,7,9
-h, --help
打印帮助信息
-V, --version
打印版本信息

如果需要设定,那么需要拥有 CAP_SYS_NICE 的权限;如果要获取设定信息,没有任何权限要求。

taskset 命令属于 util-linux-ng 包,可以使用 yum 直接安装。

8. 在Linux系统上,多个线程能否同时使用多个CPU核心有人说能,有人说不能

与超线程CPU在逻辑上模拟双核不同,多核CPU每个核心都可以独立执行一个线程,是真正意义的多个物理CPU。
第二个问题,如果你的程序的线程数少于CPU的核心数,且系统此时没有其他进程同时运行,那么这个程序的每个线程会享有一个CPU,当同时运行的线程数多于CPU核心数时,CPU会采用一定的调度算法每隔一段时间就将这些线程调入或调出CPU,以确保每个线程都能分享一部分CPU时间,实现多线程并发。

9. Linux 如何绑定指定线程在某个固定CPU上

大概的介绍一下Linux 的指定CPU运行,包括进程和线程。linux下的top命令是可以查看当前的cpu的运行状态,按1可以查看系统有多少个CPU,以及每个CPU的运行状态。
可是如何查看线程的CPU呢?top
-Hp pid,pid就是你当前程序的进程号,如果是多线程的话,是可以查看进程内所有线程的CPU和内存使用情况。

pstree可以查看主次线程,同样的pstree -p pid。可以查看进程的线程情况。

taskset这个其实才是重点,可以查看以及设置当前进程或线程运行的CPU(设置亲和力)。

taskset -pc pid,查看当前进程的cpu,当然有的时候不只是一个,taskset -pc cpu_num pid ,cpu_num就是设置的cpu。

这样的话基本的命令和操作其实大家都知道了,接下来就是在代码中完成这些操作,并通过命令去验证代码的成功率。

进程制定CPU运行:

[cpp] view plain
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/sysinfo.h>
#include<unistd.h>
#define __USE_GNU
#include<sched.h>
#include<ctype.h>
#include<string.h>

int main(int argc, char* argv[])
{
//sysconf获取有几个CPU
int num = sysconf(_SC_NPROCESSORS_CONF);
int created_thread = 0;
int myid;
int i;
int j = 0;

//原理其实很简单,就是通过cpu_set_t进行位与操作
cpu_set_t mask;
cpu_set_t get;

if (argc != 2)
{
printf("usage : ./cpu num\n");
exit(1);
}

myid = atoi(argv[1]);

printf("system has %i processor(s). \n", num);

//先进行清空,然后设置掩码
CPU_ZERO(&mask);
CPU_SET(myid, &mask);

//设置进程的亲和力
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
{
printf("warning: could not set CPU affinity, continuing...\n");
}
while (1)
{

CPU_ZERO(&get);
//获取当前进程的亲和力
if (sched_getaffinity(0, sizeof(get), &get) == -1)
{
printf("warning: cound not get cpu affinity, continuing...\n");
}
for (i = 0; i < num; i++)
{
if (CPU_ISSET(i, &get))
{
printf("this process %d is running processor : %d\n",getpid(), i);
}
}
}
return 0;
}

进程设置CPU运行,其实只能是单线程。多线程设定CPU如下:

[cpp] view plain
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>

void *myfun(void *arg)
{
cpu_set_t mask;
cpu_set_t get;
char buf[256];
int i;
int j;
//同样的先去获取CPU的个数
int num = sysconf(_SC_NPROCESSORS_CONF);
printf("system has %d processor(s)\n", num);

for (i = 0; i < num; i++) {
CPU_ZERO(&mask);
CPU_SET(i, &mask);
//这个其实和设置进程的亲和力基本是一样的
if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
fprintf(stderr, "set thread affinity failed\n");
}
CPU_ZERO(&get);
if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) {
fprintf(stderr, "get thread affinity failed\n");
}
for (j = 0; j < num; j++)
{
if (CPU_ISSET(j, &get))
{
printf("thread %d is running in processor %d\n", (int)pthread_self(), j);
}
}
j = 0;
while (j++ < 100000000) {
memset(buf, 0, sizeof(buf));
}
}
pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
pthread_t tid;
if (pthread_create(&tid, NULL, (void *)myfun, NULL) != 0)
{
fprintf(stderr, "thread create failed\n");
return -1;
}
pthread_join(tid, NULL);
return 0;
}

热点内容
scratch少儿编程课程 发布:2025-04-16 17:11:44 浏览:637
荣耀x10从哪里设置密码 发布:2025-04-16 17:11:43 浏览:366
java从入门到精通视频 发布:2025-04-16 17:11:43 浏览:82
php微信接口教程 发布:2025-04-16 17:07:30 浏览:307
android实现阴影 发布:2025-04-16 16:50:08 浏览:789
粉笔直播课缓存 发布:2025-04-16 16:31:21 浏览:339
机顶盒都有什么配置 发布:2025-04-16 16:24:37 浏览:210
编写手游反编译都需要学习什么 发布:2025-04-16 16:19:36 浏览:810
proteus编译文件位置 发布:2025-04-16 16:18:44 浏览:364
土压缩的本质 发布:2025-04-16 16:13:21 浏览:590