CPUSet for Python 3
cpuset-py3 is a Python 3 compatible fork of the original cpuset library, providing functionalities to query and manipulate CPU sets (processor affinity) on Linux systems. It allows creating, modifying, and applying CPU sets to processes and threads, facilitating fine-grained control over CPU core usage. The current version is 1.0.2, and it's maintained on an as-needed basis rather than a strict release cadence.
Common errors
-
ModuleNotFoundError: No module named 'cpuset'
cause The `cpuset-py3` package has not been installed, or the Python interpreter is not in an environment where it's installed.fixInstall the library using `pip install cpuset-py3`. -
PermissionError: [Errno 1] Operation not permitted: 'cpuset'
cause Attempting to change process or thread CPU affinity without sufficient operating system permissions.fixRun the Python script with root privileges (e.g., `sudo python your_script.py`) or ensure the executing user/process has the `CAP_SYS_NICE` capability. -
AttributeError: module 'cpuset' has no attribute 'CPUSet'
cause You likely installed the old `cpuset` (Python 2) package instead of `cpuset-py3`, which has a different internal structure or is incompatible with Python 3.fixUninstall the incorrect package (`pip uninstall cpuset`) and then install the correct one (`pip install cpuset-py3`).
Warnings
- gotcha This library is designed specifically for Linux systems. Functions for querying and setting CPU affinity (`get_cpuset_for_current_process`, `set_cpuset_for_current_process`, etc.) will not function correctly or might raise errors on other operating systems like macOS or Windows.
- gotcha Setting CPU affinity for processes or threads often requires elevated privileges (e.g., root access or specific Linux capabilities like CAP_SYS_NICE). Operations like `set_cpuset_for_current_process` might fail with `PermissionError` if not run with sufficient permissions.
- gotcha Be careful to install `cpuset-py3` for Python 3 compatibility. There is an older, incompatible package named `cpuset` on PyPI which is intended for Python 2 and will cause `AttributeError` or unexpected behavior in Python 3 environments.
- gotcha The `as_bitmask()` method returns an integer bitmask where each bit corresponds to a CPU ID. For larger or sparsely populated CPU sets, interpreting this raw bitmask can be complex or unintuitive compared to list or string representations.
Install
-
pip install cpuset-py3
Imports
- CPUSet
from cpuset import CPUSet
import cpuset; s = cpuset.CPUSet()
- set_cpuset_for_current_process
import cpuset; cpuset.set_cpuset_for_current_process(...)
Quickstart
import cpuset
import platform
print(f"Running on OS: {platform.system()}\n")
# Create a new empty cpuset
s = cpuset.CPUSet()
s.add_cpu(0)
s.add_cpu(1)
s.add_cpu(2)
print(f"Created CPUSet (0,1,2): {s.as_list()}")
print(f"As string: {s.as_str()}")
print(f"As canonical string: {s.as_canonical_str()}") # will be "0-2"
print(f"As bitmask: {hex(s.as_bitmask())}") # 0x7
# Create from a string representation
s_from_str = cpuset.CPUSet("0-3,5")
print(f"\nCPUSet from string '0-3,5': {s_from_str.as_list()}")
if platform.system() == "Linux":
print("\nAttempting to query current process affinity (Linux-only):")
try:
current_affinity = cpuset.get_cpuset_for_current_process()
print(f" Current process affinity: {current_affinity.as_list()}")
# Uncomment to attempt setting affinity (requires appropriate permissions):
# print(f" Attempting to set process affinity to {s.as_list()}...")
# cpuset.set_cpuset_for_current_process(s)
# updated_affinity = cpuset.get_cpuset_for_current_process()
# print(f" Updated process affinity: {updated_affinity.as_list()}")
except PermissionError:
print(" Permission denied to get/set process affinity. Try running with sudo or check capabilities.")
except Exception as e:
print(f" An error occurred during system affinity call: {e}")
else:
print("\nSystem affinity functions (get/set) are only available on Linux.")
print("\nOperations on CPUSet objects are generally platform-independent:")
s_union = s | cpuset.CPUSet("3-4")
print(f"Union (0-2 | 3-4): {s_union.as_list()}") # [0,1,2,3,4]
s_intersect = s & cpuset.CPUSet("1-3")
print(f"Intersection (0-2 & 1-3): {s_intersect.as_list()}") # [1,2]