Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 44feda3

Browse files
committed
Issue #17914: Add os.cpu_count(). Patch by Yogesh Chaudhari, based on an
initial patch by Trent Nelson.
1 parent 93c6770 commit 44feda3

6 files changed

Lines changed: 94 additions & 26 deletions

File tree

Doc/library/multiprocessing.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,9 @@ Miscellaneous
702702
Return the number of CPUs in the system. May raise
703703
:exc:`NotImplementedError`.
704704

705+
.. seealso::
706+
:func:`os.cpu_count`
707+
705708
.. function:: current_process()
706709

707710
Return the :class:`Process` object corresponding to the current process.

Doc/library/os.rst

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3155,10 +3155,6 @@ operating system.
31553155
Return the set of CPUs the process with PID *pid* (or the current process
31563156
if zero) is restricted to.
31573157

3158-
.. seealso::
3159-
:func:`multiprocessing.cpu_count` returns the number of CPUs in the
3160-
system.
3161-
31623158

31633159
.. _os-path:
31643160

@@ -3196,6 +3192,13 @@ Miscellaneous System Information
31963192
Availability: Unix.
31973193

31983194

3195+
.. function:: cpu_count()
3196+
3197+
Return the number of CPUs in the system. Returns None if undetermined.
3198+
3199+
.. versionadded:: 3.4
3200+
3201+
31993202
.. function:: getloadavg()
32003203

32013204
Return the number of processes in the system run queue averaged over the last

Lib/multiprocessing/__init__.py

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85,30 +85,11 @@ def cpu_count():
8585
'''
8686
Returns the number of CPUs in the system
8787
'''
88-
if sys.platform == 'win32':
89-
try:
90-
num = int(os.environ['NUMBER_OF_PROCESSORS'])
91-
except (ValueError, KeyError):
92-
num = 0
93-
elif 'bsd' in sys.platform or sys.platform == 'darwin':
94-
comm = '/sbin/sysctl -n hw.ncpu'
95-
if sys.platform == 'darwin':
96-
comm = '/usr' + comm
97-
try:
98-
with os.popen(comm) as p:
99-
num = int(p.read())
100-
except ValueError:
101-
num = 0
88+
num = os.cpu_count()
89+
if num is None:
90+
raise NotImplementedError('cannot determine number of cpus')
10291
else:
103-
try:
104-
num = os.sysconf('SC_NPROCESSORS_ONLN')
105-
except (ValueError, OSError, AttributeError):
106-
num = 0
107-
108-
if num >= 1:
10992
return num
110-
else:
111-
raise NotImplementedError('cannot determine number of cpus')
11293

11394
def freeze_support():
11495
'''

Lib/test/test_os.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,15 @@ def test_oserror_filename(self):
22162216
else:
22172217
self.fail("No exception thrown by {}".format(func))
22182218

2219+
class CPUCountTests(unittest.TestCase):
2220+
def test_cpu_count(self):
2221+
cpus = os.cpu_count()
2222+
if cpus is not None:
2223+
self.assertIsInstance(cpus, int)
2224+
self.assertGreater(cpus, 0)
2225+
else:
2226+
self.skipTest("Could not determine the number of CPUs")
2227+
22192228
@support.reap_threads
22202229
def test_main():
22212230
support.run_unittest(
@@ -2246,6 +2255,7 @@ def test_main():
22462255
TermsizeTests,
22472256
OSErrorTests,
22482257
RemoveDirsTests,
2258+
CPUCountTests,
22492259
)
22502260

22512261
if __name__ == "__main__":

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ Core and Builtins
9999
Library
100100
-------
101101

102+
- Issue #17914: Add os.cpu_count(). Patch by Yogesh Chaudhari, based on an
103+
initial patch by Trent Nelson.
104+
102105
- Issue #17980: Fix possible abuse of ssl.match_hostname() for denial of
103106
service using certificates with many wildcards (CVE-2013-2099).
104107

Modules/posixmodule.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,18 @@ corresponding Unix manual entries for more information on calls.");
113113
#include <dlfcn.h>
114114
#endif
115115

116+
#ifdef __hpux
117+
#include <sys/mpctl.h>
118+
#endif
119+
120+
#if defined(__DragonFly__) || \
121+
defined(__OpenBSD__) || \
122+
defined(__FreeBSD__) || \
123+
defined(__NetBSD__) || \
124+
defined(__APPLE__)
125+
#include <sys/sysctl.h>
126+
#endif
127+
116128
#if defined(MS_WINDOWS)
117129
# define TERMSIZE_USE_CONIO
118130
#elif defined(HAVE_SYS_IOCTL_H)
@@ -10302,6 +10314,60 @@ get_terminal_size(PyObject *self, PyObject *args)
1030210314
}
1030310315
#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
1030410316

10317+
PyDoc_STRVAR(posix_cpu_count__doc__,
10318+
"cpu_count() -> integer\n\n\
10319+
Return the number of CPUs in the system, or None if this value cannot be\n\
10320+
established.");
10321+
10322+
#if defined(__DragonFly__) || \
10323+
defined(__OpenBSD__) || \
10324+
defined(__FreeBSD__) || \
10325+
defined(__NetBSD__) || \
10326+
defined(__APPLE__)
10327+
static long
10328+
_bsd_cpu_count(void)
10329+
{
10330+
long ncpu = 0;
10331+
int mib[2];
10332+
size_t len = sizeof(int);
10333+
10334+
mib[0] = CTL_HW;
10335+
mib[1] = HW_NCPU;
10336+
if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == 0)
10337+
return ncpu;
10338+
else
10339+
return 0;
10340+
}
10341+
#endif
10342+
10343+
static PyObject *
10344+
posix_cpu_count(PyObject *self)
10345+
{
10346+
long ncpu = 0;
10347+
#ifdef MS_WINDOWS
10348+
SYSTEM_INFO sysinfo;
10349+
GetSystemInfo(&sysinfo);
10350+
ncpu = sysinfo.dwNumberOfProcessors;
10351+
#elif defined(__hpux)
10352+
ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10353+
#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10354+
ncpu = sysconf(_SC_NPROCESSORS_ONLN);
10355+
#elif defined(__APPLE__)
10356+
size_t len = sizeof(int);
10357+
if (sysctlnametomib("hw.logicalcpu", &ncpu, &len, NULL, 0) != 0)
10358+
ncpu = _bsd_cpu_count();
10359+
#elif defined(__DragonFly__) || \
10360+
defined(__OpenBSD__) || \
10361+
defined(__FreeBSD__) || \
10362+
defined(__NetBSD__)
10363+
ncpu = _bsd_cpu_count();
10364+
#endif
10365+
if (ncpu >= 1)
10366+
return PyLong_FromLong(ncpu);
10367+
else
10368+
Py_RETURN_NONE;
10369+
}
10370+
1030510371

1030610372
static PyMethodDef posix_methods[] = {
1030710373
{"access", (PyCFunction)posix_access,
@@ -10747,6 +10813,8 @@ static PyMethodDef posix_methods[] = {
1074710813
#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
1074810814
{"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
1074910815
#endif
10816+
{"cpu_count", (PyCFunction)posix_cpu_count,
10817+
METH_NOARGS, posix_cpu_count__doc__},
1075010818
{NULL, NULL} /* Sentinel */
1075110819
};
1075210820

0 commit comments

Comments
 (0)