pythonsystem-information

How to find out the number of CPUs using python


I want to know the number of CPUs on the local machine using Python. The result should be user/real as output by time(1) when called with an optimally scaling userspace-only program.


Solution

  • If you're interested into the number of processors available to your current process, you have to check cpuset first. Otherwise (or if cpuset is not in use), multiprocessing.cpu_count() is the way to go in Python 2.6 and newer. The following method falls back to a couple of alternative methods in older versions of Python:

    import os
    import re
    import subprocess
    
    
    def available_cpu_count():
        """ Number of available virtual or physical CPUs on this system, i.e.
        user/real as output by time(1) when called with an optimally scaling
        userspace-only program"""
    
        # cpuset
        # cpuset may restrict the number of *available* processors
        try:
            m = re.search(r'(?m)^Cpus_allowed:\s*(.*)$',
                          open('/proc/self/status').read())
            if m:
                res = bin(int(m.group(1).replace(',', ''), 16)).count('1')
                if res > 0:
                    return res
        except IOError:
            pass
    
        # Python 2.6+
        try:
            import multiprocessing
            return multiprocessing.cpu_count()
        except (ImportError, NotImplementedError):
            pass
    
        # https://github.com/giampaolo/psutil
        try:
            import psutil
            return psutil.cpu_count()   # psutil.NUM_CPUS on old versions
        except (ImportError, AttributeError):
            pass
    
        # POSIX
        try:
            res = int(os.sysconf('SC_NPROCESSORS_ONLN'))
    
            if res > 0:
                return res
        except (AttributeError, ValueError):
            pass
    
        # Windows
        try:
            res = int(os.environ['NUMBER_OF_PROCESSORS'])
    
            if res > 0:
                return res
        except (KeyError, ValueError):
            pass
    
        # jython
        try:
            from java.lang import Runtime
            runtime = Runtime.getRuntime()
            res = runtime.availableProcessors()
            if res > 0:
                return res
        except ImportError:
            pass
    
        # BSD
        try:
            sysctl = subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
                                      stdout=subprocess.PIPE)
            scStdout = sysctl.communicate()[0]
            res = int(scStdout)
    
            if res > 0:
                return res
        except (OSError, ValueError):
            pass
    
        # Linux
        try:
            res = open('/proc/cpuinfo').read().count('processor\t:')
    
            if res > 0:
                return res
        except IOError:
            pass
    
        # Solaris
        try:
            pseudoDevices = os.listdir('/devices/pseudo/')
            res = 0
            for pd in pseudoDevices:
                if re.match(r'^cpuid@[0-9]+$', pd):
                    res += 1
    
            if res > 0:
                return res
        except OSError:
            pass
    
        # Other UNIXes (heuristic)
        try:
            try:
                dmesg = open('/var/run/dmesg.boot').read()
            except IOError:
                dmesgProcess = subprocess.Popen(['dmesg'], stdout=subprocess.PIPE)
                dmesg = dmesgProcess.communicate()[0]
    
            res = 0
            while '\ncpu' + str(res) + ':' in dmesg:
                res += 1
    
            if res > 0:
                return res
        except OSError:
            pass
    
        raise Exception('Can not determine number of CPUs on this system')