has been termed 'a standard way to be nonstandard' (or, alternately, 'a portable way to be nonportable'). That is, when you use any implementation of Pthreads that supports the priority scheduling option, you can write a portable program that creates threads running in SCHED_OTHER policy, but the behavior of that program is nonportable. (The official explanation of SCHED_OTHER is that it provides a portable way for a program to declare that it does not need a realtime scheduling policy.)
The SCHED_OTHER policy may be an alias for SCHED_FIFO, or it may be SCHED_RR, or it may be something entirely different. The real problem with this ambiguity is not that you don't know what SCHED_OTHER does, but that you have no way of knowing what scheduling parameters it might require. Because the meaning of SCHED_OTHER is undefined, it does not necessarily use the sched_priority member of the struct sched_param structure, and it may require additional, nonstandard members that an implementation may add to the structure. If there's any point to this, it is simply that SCHED_OTHER is not portable. If you write any code that uses SCHED_OTHER you should be aware that the code is not portable — you are, by definition, depending on the SCHED_OTHER of the particular Pthreads implementation for which you wrote the code.
The pthread_attr_setschedpolicy
and pthread_attr_setschedparam
, specify the explicit scheduling policy and parameters for the attributes object. Pthreads does not specify a default value for either of these attributes, which means that each implementation may choose some 'appropriate' value. A realtime operating system intended for embedded controller applications, for example, might choose to create threads by default with SCHED_FIFO policy, and, perhaps, some medium-range priority.
Most multiuser operating systems are more likely to use a nonstandard 'time-share' scheduling policy by default, causing threads to be scheduled more or less as processes have always been scheduled. The system may, for example, temporarily reduce the priority of 'CPU hogs' so that they cannot prevent other threads from making progress.
One example of a multiuser operating system is Digital UNIX, which supports two nonstandard timeshare scheduling policies. The
When you set the scheduling policy or priority attributes in an attributes object,you must also set the inheritsched attribute!
The pthread_attr_setinheritsched
, controls whether a thread you create inherits scheduling information from the creating thread, or uses the explicit scheduling information in the
Set the
58-118 The following program, sched_attr.c, shows how to use an attributes object to create a thread with an explicit scheduling policy and priority. Notice that it uses conditional code to determine whether the priority scheduling feature of Pthreads is supported at compilation time. It will print a message if the option is not supported and continue, although the program in that case will not do much. (It creates a thread with default scheduling behavior, which can only say that it ran.)
Although Solaris 2.5 defines _POSIX_THREAD_PRIORITY_SCHEDULING, it does not support the POSIX realtime scheduling policies, and attempting to set the policy attribute to SCHED_RR would fail. This program treats Solaris as it did not define the _POSIX_THREAD_PRIORITY_SCHEDULING option.
¦ sched_attr.c
1 #include <unistd.h>
2 #include <pthread.h>
3 #include <sched.h>
4 #include 'errors.h' 5
6 /*
7 * Thread start routine. If priority scheduling is supported,
8 * report the thread's scheduling attributes.
9 */
10 void *thread_routine (void *arg)
11 {
12 int my_policy;
13 struct sched_param my_param;
14 int status;
15
16 /*
17 * If the priority scheduling option is not defined, then we
18 * can do nothing with the output of pthread_getschedparam,
19 * so just report that the thread ran, and exit.
20 */
21 #if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined (sun)
22 status = pthread_getschedparam (
23 pthread_self (), &my_policy, &my_param);
24 if (status != 0)
25 err_abort (status, 'Get sched');
26 printf ('thread_routine running at %s/%d
',
27 (my_policy == SCHED_FIFO ? 'FIFO'
28 : (my_policy == SCHED_RR ? 'RR'
29 : (my_policy == SCHED_OTHER ? 'OTHER'
30 : 'unknown'))),
31 my_param.sched_priority);
32 #else
33 printf ('thread_routine running
');
34 #endif
35 return NULL;
36 }
37
38 int main (int argc, char *argv[])
39 {
40 pthread_t thread_id;
41 pthread_attr_t thread_attr;
42 int thread_policy;
43 struct sched_param thread_param;
44 int status, rr_min_priority, rr_max_priority;
45
46 status = pthread_attr_init (&thread_attr);
47 if (status != 0)
4 8 err_abort (status, 'Init attr');
49
50 /*