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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux单进程如何实现多核cpu多线程分配?相关的知识,希望对你有一定的参考价值。

服务器安装64位linux,运行某测试程序,始终达不到程序的效果,发现主要问题出在cpu占用率上,双cpu8核但程序运行下来只能使用一个线程。程序本身不可修改,现在的问题就是如何将此程序多线程化以达到效果。是否可以通过命令或修改内核参数使程序占用多个内核并行运行呢?(程序本身没有问题,瓶颈在cpu使用上,无法分配多线程)

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


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


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

int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,
const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, 
cpu_set_t *cpuset);
从函数名以及参数名都很明了,唯一需要点解释下的可能就是cpu_set_t这个结构体了。这个结构体的理解类似于select中的fd_set,可以理解为cpu集,也是通过约定好的宏来进行清除、设置以及判断:
//初始化,设为空
void CPU_ZERO (cpu_set_t *set); 
//将某个cpu加入cpu集中 
void CPU_SET (int cpu, cpu_set_t *set); 
//将某个cpu从cpu集中移出 
void CPU_CLR (int cpu, cpu_set_t *set); 
//判断某个cpu是否已在cpu集中设置了 
int CPU_ISSET (int cpu, const cpu_set_t *set);

参考技术A "程序本身不可修改,现在的问题就是如何将此程序多线程化以达到效果"

---- 如果不能修改程序本身,怎么变成多线程程序??? 楼主还是先去搞搞清楚进程、线程的基本概念吧。追问

就是说除非更改程序,否则无法通过其他手段达到单进程使用多线程对吗?我一直以来认为这是内核调用的问题,是否能通过软件实现进程多线程话呢?

追答

算了,帮你普及一点基本概念:

一个进程, 可能只有一个线程,此时叫 单线程进程,对于这样的进程,不管你用什么 CPU,什么工具,什么调用,在任何时刻,最多只能有 一个 cpu(内核)执行这个进程。

一个(linux)进程,可以通过 pthread 线程库提供的接口 (但是这是需要在这个程序的源码里使用的接口,对于已有的程序,必须修改其源码,重新编译生成新的程序才行),实现进程内拥有多条线程,此时叫多线程进程,只有多线程进程才能利用到多核处理器,即不同的cpu核心执行不同的线程。

追问

嗯,线程的概念和cpu搞糊涂了,谢谢了

本回答被提问者采纳

多进程和多线程

多进程

我们通常所得操作系统是多任务的OS。这个任务一般指的就是进程,比如:我们听音乐和写文档对于我们来说是同时执行的。那么是如何实现的呢?这主要是操作系统上的时间片,通常时间很短。每个时间片内将CPU分配给某一个任务,时间片结束,CPU将自动回收,再分配给另外任务。从外部看,所有任务是同时在执行。但是在CPU上,任务是按照串行依次运行(单核CPU)。如果是多核,多个进程任务可以并行。但是单个核上,多进程只能串行执行。

多进程的优缺点


优点:


可以同时运行多个任务
程序因IO堵塞时(例如键盘的输入),可以释放CPU,让CPU为其他程序服务
当CPU有多个核时,可以为多个程序同时服务

缺点:


过于笨重,不好管理。
进程之前切换代价过大。

多线程


概念:一个程序可以包括多个子任务,可串/并行,每个子任务可以称为一个线程。

多线程在一个子任务发生IO堵塞时可以让cpu切换到另一个子任务,这样cpu知识在一个程序之间进行切换,所消耗的代价较小。例如:你让一个扫地阿姨帮你扫地,但是这个房间锁了,此时你只需要让她扫隔壁的房子就好。如果是进程的切换相当于你让她去扫另一栋楼,这时所消耗的时间就很多了。

多线程和多进程对比


– 线程共享数据
– 线程通讯更高效
– 线程更轻量级,更容易切换
– 多个线程更容易管理

Java中多线程的创建

技术图片
技术图片
技术图片
技术图片

public class MutiThread {

    public static void main(String[] args) {
       // new Thread1().start();//实例化之后可以直接start
        new Thread(new Thread2()).start();//必须借助中间类Thread进行start
        while(true){
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

/**
 * 实现多线程编程的方式1:继承Thread,重写run方法
 *
 */
class Thread1 extends Thread{
    @Override
    //线程的代码段,当执行start()时,线程从此出开始执行
    public void run() {
        while(true){
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 实现多线程编程的方式1:实现Runnable,实现run方法
 *
 */
class Thread2 implements Runnable{

    @Override
    public void run() {
        while(true){
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Java中多线程的启动

技术图片
技术图片
技术图片

java多线程实现对比


技术图片
技术图片
技术图片
技术图片

以上是关于linux单进程如何实现多核cpu多线程分配?的主要内容,如果未能解决你的问题,请参考以下文章

C++ openmp并行程序在多核linux上如何最大化使用cpu

windows 怎样在调度线程到多核

浅谈多核CPU多线程多进程

Node玩转多进程

Linux系列:多进程多线程与CPU的关系

单进程单线程的Redis如何能够高并发