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

Skip to content

Commit 94b580d

Browse files
committed
expose sched.h functions (closes #12655)
1 parent 4e4d5d2 commit 94b580d

7 files changed

Lines changed: 877 additions & 5 deletions

File tree

Doc/library/os.rst

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2744,6 +2744,155 @@ used to determine the disposition of a process.
27442744
Availability: Unix.
27452745

27462746

2747+
Interface to the scheduler
2748+
--------------------------
2749+
2750+
These functions control how a process is allocated CPU time by the operating
2751+
system. They are only available on some Unix platforms. For more detailed
2752+
information, consult your Unix manpages.
2753+
2754+
.. versionadded:: 3.3
2755+
2756+
The following scheduling policies are exposed if they are a supported by the
2757+
operating system.
2758+
2759+
.. data:: SCHED_OTHER
2760+
2761+
The default scheduling policy.
2762+
2763+
.. data:: SCHED_BATCH
2764+
2765+
Scheduling policy for CPU-intensive processes that tries to preserve
2766+
interactivity on the rest of the computer.
2767+
2768+
.. data:: SCHED_IDLE
2769+
2770+
Scheduling policy for extremely low priority background tasks.
2771+
2772+
.. data:: SCHED_SPORADIC
2773+
2774+
Scheduling policy for sporadic server programs.
2775+
2776+
.. data:: SCHED_FIFO
2777+
2778+
A First In First Out scheduling policy.
2779+
2780+
.. data:: SCHED_RR
2781+
2782+
A round-robin scheduling policy.
2783+
2784+
.. data:: SCHED_RESET_ON_FORK
2785+
2786+
This flag can OR'ed with any other scheduling policy. When a process with
2787+
this flag set forks, its child's scheduling policy and priority are reset to
2788+
the default.
2789+
2790+
2791+
.. class:: sched_param(sched_priority)
2792+
2793+
This class represents tunable scheduling parameters used in
2794+
:func:`sched_setparam`, :func:`sched_setscheduler`, and
2795+
:func:`sched_getparam`. It is immutable.
2796+
2797+
At the moment, there is only one possible parameter:
2798+
2799+
.. attribute:: sched_priority
2800+
2801+
The scheduling priority for a scheduling policy.
2802+
2803+
2804+
.. function:: sched_get_priority_min(policy)
2805+
2806+
Get the minimum priority value for *policy*. *policy* is one of the
2807+
scheduling policy constants above.
2808+
2809+
2810+
.. function:: sched_get_priority_max(policy)
2811+
2812+
Get the maximum priority value for *policy*. *policy* is one of the
2813+
scheduling policy constants above.
2814+
2815+
2816+
.. function:: sched_setscheduler(pid, policy, param)
2817+
2818+
Set the scheduling policy for the process with PID *pid*. A *pid* of 0 means
2819+
the calling process. *policy* is one of the scheduling policy constants
2820+
above. *param* is a :class:`sched_param` instance.
2821+
2822+
2823+
.. function:: sched_getscheduler(pid)
2824+
2825+
Return the scheduling policy for the process with PID *pid*. A *pid* of 0
2826+
means the calling process. The result is one of the scheduling policy
2827+
constants above.
2828+
2829+
2830+
.. function:: sched_setparam(pid, param)
2831+
2832+
Set a scheduling parameters for the process with PID *pid*. A *pid* of 0 means
2833+
the calling process. *param* is a :class:`sched_param` instance.
2834+
2835+
2836+
.. function:: sched_getparam(pid)
2837+
2838+
Return the scheduling parameters as a :class:`sched_param` instance for the
2839+
process with PID *pid*. A *pid* of 0 means the calling process.
2840+
2841+
2842+
.. function:: sched_rr_get_interval(pid)
2843+
2844+
Return the round-robin quantum in seconds for the process with PID *pid*. A
2845+
*pid* of 0 means the calling process.
2846+
2847+
2848+
.. function:: sched_yield()
2849+
2850+
Voluntarily relinquish the CPU.
2851+
2852+
2853+
.. class:: cpu_set(ncpus)
2854+
2855+
:class:`cpu_set` represents a set of CPUs on which a process is eligible to
2856+
run. *ncpus* is the number of CPUs the set should describe. Methods on
2857+
:class:`cpu_set` allow CPUs to be add or removed.
2858+
2859+
:class:`cpu_set` supports the AND, OR, and XOR bitwise operations. For
2860+
example, given two cpu_sets, ``one`` and ``two``, ``one | two`` returns a
2861+
:class:`cpu_set` containing the cpus enabled both in ``one`` and ``two``.
2862+
2863+
.. method:: set(i)
2864+
2865+
Enable CPU *i*.
2866+
2867+
.. method:: clear(i)
2868+
2869+
Remove CPU *i*.
2870+
2871+
.. method:: isset(i)
2872+
2873+
Return ``True`` if CPU *i* is enabled in the set.
2874+
2875+
.. method:: count()
2876+
2877+
Return the number of enabled CPUs in the set.
2878+
2879+
.. method:: zero()
2880+
2881+
Clear the set completely.
2882+
2883+
2884+
.. function:: sched_setaffinity(pid, mask)
2885+
2886+
Restrict the process with PID *pid* to a set of CPUs. *mask* is a
2887+
:class:`cpu_set` instance.
2888+
2889+
2890+
.. function:: sched_getaffinity(pid, size)
2891+
2892+
Return the :class:`cpu_set` the process with PID *pid* is restricted to. The
2893+
result will contain *size* CPUs.
2894+
2895+
27472896
.. _os-path:
27482897

27492898
Miscellaneous System Information

Lib/test/test_posix.py

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,138 @@ def test_mkfifoat(self):
829829
finally:
830830
posix.close(f)
831831

832+
requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
833+
"don't have scheduling support")
834+
835+
@requires_sched_h
836+
def test_sched_yield(self):
837+
# This has no error conditions (at least on Linux).
838+
posix.sched_yield()
839+
840+
@requires_sched_h
841+
def test_sched_priority(self):
842+
# Round-robin usually has interesting priorities.
843+
pol = posix.SCHED_RR
844+
lo = posix.sched_get_priority_min(pol)
845+
hi = posix.sched_get_priority_max(pol)
846+
self.assertIsInstance(lo, int)
847+
self.assertIsInstance(hi, int)
848+
self.assertGreaterEqual(hi, lo)
849+
self.assertRaises(OSError, posix.sched_get_priority_min, -23)
850+
self.assertRaises(OSError, posix.sched_get_priority_max, -23)
851+
852+
@requires_sched_h
853+
def test_get_and_set_scheduler_and_param(self):
854+
possible_schedulers = [sched for name, sched in posix.__dict__.items()
855+
if name.startswith("SCHED_")]
856+
mine = posix.sched_getscheduler(0)
857+
self.assertIn(mine, possible_schedulers)
858+
try:
859+
init = posix.sched_getscheduler(1)
860+
except OSError as e:
861+
if e.errno != errno.EPERM:
862+
raise
863+
else:
864+
self.assertIn(init, possible_schedulers)
865+
self.assertRaises(OSError, posix.sched_getscheduler, -1)
866+
self.assertRaises(OSError, posix.sched_getparam, -1)
867+
param = posix.sched_getparam(0)
868+
self.assertIsInstance(param.sched_priority, int)
869+
posix.sched_setscheduler(0, mine, param)
870+
posix.sched_setparam(0, param)
871+
self.assertRaises(OSError, posix.sched_setparam, -1, param)
872+
self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
873+
self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
874+
self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
875+
param = posix.sched_param(None)
876+
self.assertRaises(TypeError, posix.sched_setparam, 0, param)
877+
large = 214748364700
878+
param = posix.sched_param(large)
879+
self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
880+
param = posix.sched_param(sched_priority=-large)
881+
self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
882+
883+
@requires_sched_h
884+
def test_sched_rr_get_interval(self):
885+
interval = posix.sched_rr_get_interval(0)
886+
self.assertIsInstance(interval, float)
887+
# Reasonable constraints, I think.
888+
self.assertGreaterEqual(interval, 0.)
889+
self.assertLess(interval, 1.)
890+
891+
@requires_sched_h
892+
def test_sched_affinity(self):
893+
mask = posix.sched_getaffinity(0, 1024)
894+
self.assertGreaterEqual(mask.count(), 1)
895+
self.assertIsInstance(mask, posix.cpu_set)
896+
self.assertRaises(OSError, posix.sched_getaffinity, -1, 1024)
897+
empty = posix.cpu_set(10)
898+
posix.sched_setaffinity(0, mask)
899+
self.assertRaises(OSError, posix.sched_setaffinity, 0, empty)
900+
self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
901+
902+
@requires_sched_h
903+
def test_cpu_set_basic(self):
904+
s = posix.cpu_set(10)
905+
self.assertEqual(len(s), 10)
906+
self.assertEqual(s.count(), 0)
907+
s.set(0)
908+
s.set(9)
909+
self.assertTrue(s.isset(0))
910+
self.assertTrue(s.isset(9))
911+
self.assertFalse(s.isset(5))
912+
self.assertEqual(s.count(), 2)
913+
s.clear(0)
914+
self.assertFalse(s.isset(0))
915+
self.assertEqual(s.count(), 1)
916+
s.zero()
917+
self.assertFalse(s.isset(0))
918+
self.assertFalse(s.isset(9))
919+
self.assertEqual(s.count(), 0)
920+
self.assertRaises(ValueError, s.set, -1)
921+
self.assertRaises(ValueError, s.set, 10)
922+
self.assertRaises(ValueError, s.clear, -1)
923+
self.assertRaises(ValueError, s.clear, 10)
924+
self.assertRaises(ValueError, s.isset, -1)
925+
self.assertRaises(ValueError, s.isset, 10)
926+
927+
@requires_sched_h
928+
def test_cpu_set_cmp(self):
929+
self.assertNotEqual(posix.cpu_set(11), posix.cpu_set(12))
930+
l = posix.cpu_set(10)
931+
r = posix.cpu_set(10)
932+
self.assertEqual(l, r)
933+
l.set(1)
934+
self.assertNotEqual(l, r)
935+
r.set(1)
936+
self.assertEqual(l, r)
937+
938+
@requires_sched_h
939+
def test_cpu_set_bitwise(self):
940+
l = posix.cpu_set(5)
941+
l.set(0)
942+
l.set(1)
943+
r = posix.cpu_set(5)
944+
r.set(1)
945+
r.set(2)
946+
b = l & r
947+
self.assertEqual(b.count(), 1)
948+
self.assertTrue(b.isset(1))
949+
b = l | r
950+
self.assertEqual(b.count(), 3)
951+
self.assertTrue(b.isset(0))
952+
self.assertTrue(b.isset(1))
953+
self.assertTrue(b.isset(2))
954+
b = l ^ r
955+
self.assertEqual(b.count(), 2)
956+
self.assertTrue(b.isset(0))
957+
self.assertFalse(b.isset(1))
958+
self.assertTrue(b.isset(2))
959+
b = l
960+
b |= r
961+
self.assertIs(b, l)
962+
self.assertEqual(l.count(), 3)
963+
832964
class PosixGroupsTester(unittest.TestCase):
833965

834966
def setUp(self):
@@ -864,7 +996,6 @@ def test_setgroups(self):
864996
posix.setgroups(groups)
865997
self.assertListEqual(groups, posix.getgroups())
866998

867-
868999
def test_main():
8691000
try:
8701001
support.run_unittest(PosixTester, PosixGroupsTester)

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,11 @@ Core and Builtins
251251
Library
252252
-------
253253

254+
- Issue #12655: Expose functions from sched.h in the os module: sched_yield(),
255+
sched_setscheduler(), sched_getscheduler(), sched_setparam(),
256+
sched_get_min_priority(), sched_get_max_priority(), sched_rr_get_interval(),
257+
sched_getaffinity(), sched_setaffinity().
258+
254259
- Issues #11104, #8688: Fix the behavior of distutils' sdist command with
255260
manually-maintained MANIFEST files.
256261

0 commit comments

Comments
 (0)