Here, I am trying to create two threads, assign priorities/policies to them and get the expected behavior.
Expected behavior: Thread which has highest priority(in this case, thread1) should execute always first. What I am seeing: Thread output gets mingled, meaning the priority is not being followed.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sched.h>
void *thread_func1 ();
void *thread_func2 ();
int main (){
pthread_t thread1, thread2;
pthread_attr_t attr1, attr2;
struct sched_param param1, param2;
int thread1_prio = 70;
int thread2_prio = 69;
int policy1, policy2;
policy1 = SCHED_RR;
policy2 = SCHED_RR;
pthread_attr_init(&attr1);
pthread_attr_init(&attr2);
param1.sched_priority = thread1_prio;
param2.sched_priority = thread2_prio;
pthread_attr_setschedparam(&attr1, ¶m1);
pthread_attr_setschedparam(&attr2, ¶m2);
pthread_attr_setschedpolicy(&attr1, policy1);
pthread_attr_setschedpolicy(&attr2, policy2);
pthread_attr_getschedparam(&attr1, ¶m1);
pthread_attr_getschedparam(&attr2, ¶m2);
pthread_attr_getschedpolicy(&attr1, &policy1);
pthread_attr_getschedpolicy(&attr2, &policy2);
pthread_create(&thread1, &attr1, thread_func1, NULL);
pthread_create(&thread2, &attr2, thread_func2, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
void *thread_func1 (void *var){
for (int i = 0; i<5; i++){
printf("Thread: 1\n");
}
return 0;
}
void *thread_func2 (void *var){
for (int i=0; i<5; i++){
printf("Thread: 2\n");
}
return 0;
}
pthread_setschedprio
, still could not get results as expected.root
Prior posting this question, I did try to follow many posts / examples, but ended up getting more confused. Any help is appreciated.
Edit: Was this not a genuine question? I mean Please correct me if it was stupid to post this and deserve downvotes as some of you already down-voted the post?
Expected behavior: Thread which has highest priority (in this case, thread1) should execute first always.
In general, Linux doesn't work like that. The underlying design revolves around time sharing, where a task's priority influences the percentage of a CPU's time the task gets and has no effect on latency or preemption. It simply isn't intended to do "highest priority task that can run does run (and preempts lower priority tasks)" like you want.
In addition:
pthread priorities are completely broken and unsupported for almost everything (except for the real-time scheduling policy that shouldn't be used by normal software, and probably shouldn't be used if you have hard real time requirements either).
nice()
is also broken, because it effects individual threads and not all threads belonging to the whole process like it's supposed to. This brokenness means that you can (sort of) use nice()
instead of pthread priorities if you're brave.
the behavior of the "priority"/nice limit is (or at least was, I haven't checked if its been fixed recently) also broken; in that regardless of what the limit is you can only reduce your task's priority and can't increase it back up to the limit. This completely breaks several common designs (e.g. "worker thread/s get a job from a queue then adjusts its priority to suit that job" and "thread pre-generates objects for future use and puts then in a pool, and adjusts its priority to meet demand (depending on how full/empty the pool is)").
The end result is that (without extreme hassles - e.g. a user-space threading layer on top of the kernel's broken mess) you're effectively left the ability to emulate a paltry "2 priority" system by abusing "SCHED_RR" (plus nice()
for insignificant/minor adjustment) as the high/medium priority and "SCHED_IDLE" as the low priority.
Mostly; it's probably best to forget about writing software that uses thread priorities properly (it's too hard, not portable and only gives part of the benefits that it should). Of course that's also the underlying problem (because most software doesn't use thread priorities, so kernel developers don't really care enough to understand how a scheduler should work and don't fix thread priority, so most software doesn't use thread priorities - it's a self perpetuating feed-back loop of idiocy that's persisted for 3 decades now).