Consider thread 1 has the higher priority than thread 2.
Is there is any sample program to simulate that thread 1 has taken the highest priority when compared to thread2?
I encountered this question because there is an option called thread priority in pthreads.
As per my knowledge thread priority is used by OS for scheduling policy and there is no control on programmer.
Is my understanding correct?
I'm not sure about "simulating", but there sure is a function to control thread priority. And it is available to the programmer.
Read the documentation for pthread_setschedparam();
Related
I would like to write a program, where several worker threads should process different tasks with different priorities. Large tasks would be processed with low priority and small tasks with a very high priority.
In a perfect world I would simply set a different priority for each kind of task, but since it is more task types than priority levels available on Windows, I think i have to set the thread priorities dynamically.
I think there should be a main thread with highest priority, working as a kind of scheduler setting the priorities of the worker threads dynamically. But I wonder what actually happens on Windows, when I call SetThreadPriority() and especially how quick the priority change is taken into account by the OS.
Ideally I need to boost the priority of a 'small task thread' within < 1 ms. Is this possible? And is there any way to change the latency of the OS (if there is any) reacting on the priority change?
The windows dispatcher (scheduler) is not a single process/thread; it is spread across the kernel. The dispatcher is generally triggered by the following events:
Thread becomes ready for execution
Thread leaves running state (e.g. quantum expires, wait state, or done)
The thread's priority changes (e.g. SetThreadPriority)
Processor affinity changes
I need to boost the priority of a 'small task thread' within < 1 ms. Is this possible?
According to 3: Yes, the dispatcher will reschedule immediately.
Ref.: Windows Internals Tour: Windows Processes, Threads and
Memory, Microsoft Academic Club 2011
I am using gcc c++ 4.7 on Debian 7. I want to set some priorities for my threads. Looks like I have to do it through pthread. I am getting confused by the scheduler policy and priority in pthread.
Q1:
I use sched_setscheduler in my c++ code to set the thread scheduler to SCHED_RR. Will all the threads in this process use this real time scheduler? Or I can have different scheduler policy in one process for different threads?
Q2:
Does the thread priority take effect only inside the process or across multiple process? E.g. I have two processes both using SCHED_RR. One has a thread with priority 99, the other has a thread with priority 98. Does the former thread has a higher priority over the latter? What if the threads use different scheduler, how to compare their priority?
Q3:
What "default" number should I use for a scheduler's priority? E.g. I use the code below:
struct sched_param param;
param.sched_priority = default_priority;
sched_setscheduler(0, SCHED_RR, ¶m));
What value should I set to the default_priority? I have some high priority thread, normal priority thread and some low priority thread in my program. Among 1-99, what number should I use for the priorities?
Q4:
Process priority and thread priority mixed. For example, I can use nice to set the process priority. If one process has lower process priority but in my code I set its thread to a high priority. Does this override the process priority setting?
I googled around and read various documents. I think I can answer my own question here.
Pthread has a contention scope attribute. It could be PTHREAD_SCOPE_SYSTEM or PTHREAD_SCOPE_PROCESS. It does not require implementation on both of them. Linux only supportes PTHREAD_SCOPE_SYSTEM, which means all threads from all processes compete with each other. Also, in Linux, thread is essentially a lightweight process. The process scheduler does not treat process and thread differently in scheduling.
Answers.
Q1:
Threads in the same process can have different scheduling policies and priorities.
Q2:
Threads compete across processes.
Q3:
I can use some arbitrary numbers. Each priority, from 1 to 99, will have its own queue in scheduling.
Q4:
The nice value is used in the Linux default SCHED_OTHER policy. When real time policy like SCHED_RR or SCHED_FIFO is used for a thread, the nice value has no effect. Since the min priority of SCHED_RR and SCHED_FIFO is 1 and SCHED_OTHER's priority can only be 0. So threads with real time policy always have scheduling preferences than non real time ones.
The answers apply to Linux only. Other OS like BSD, Solaris may have different pthread implementations.
In a project I run into a case like this (On windows 7),
When several threads are busy (all my CPU cores are busy working), there'll be delay for a thread
to receive a semaphore (which is increased from 0 to 1). It may be as long as 1.5ms.
I solve this by cache a little things and increase the semaphore value earlier.
So to me, it seems signaling a semaphore is slow, it's not immediately received by threads (especially when CPU are busy), but if you signal it earlier before some thread begin to wait on it,, there' be no delay.
I once thought event is just a semaphore with maximum value of 1,,, well, now having met this case, I'm beginning to wonder if event is faster than semaphore at noticing threads to 'wake up'.
Sorry, I tried, but didn't come out with a demo,, I'm not very good at threading yet.
EDIT:
Is it true that Event is faster than Semaphore on Windows?
1.5 milliseconds is not explained by just the overhead between different multithreading primitives.
To simplify, Threads have three states
blocked
runnable
running
If a thread is waiting on a semaphore or an event, then it's blocked. When the event is signalled, it becomes runnable.
So the real question is, "When does a runnable thread actually run?" This varies according to scheduler algorithms, etc, but obviously it needs to run on a core, and that means nothing else can be "running" on that core at the same time. The scheduler will normally 'remove' the current running thread from a core when one of the following happens
it waits on a semaphore/event, and so becomes 'blocked'
It's been running continually for a certain time (time-based, or round-robin scheduling)
A higher priority thread becomes runnable.
The 1.5 milliseconds is probably round-robin, or time-based scheduling. Your thread is runnable but just hasn't started yet. If the thread must start, and should boot out the current thread, then you can try to increase it's priority via SetThreadPriority
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686277(v=vs.85).aspx
If a thread is waiting on a semaphore and it gets signaled, the thread will in my limited testing, become running in ~10us on a box that is not overloaded.
Signaling, and subsequent dispatching onto a core, will take longer if:
The signaled thread is in another process than any thread is preempts.
Running the signaled thread requires a thread running on another core to be preempted.
The box is already overloaded with higher-priority threads.
1.5ms must represent an extreme case where your box is very busy.
In such a case, replacing the semaphore with an event is unlikely to result in any significant improvement to overall signaling latency because the bulk of the work/delay required by the inter-thread signaling is tied up the in scheduling/dispatching, which is required in either case.
I've just come across the Get/SetThreadPriority methods and they got me wondering - can a thread priority meaningfully be set higher than the owning process priority (which I don't believe can be changed programatically in the same way) ?
Are there any pitfalls to using these APIs?
Yes, you can set the thread priority to any class, including a class higher than the one of the current process. In fact, these two values are complementary and provide the base priority of the thread. You can read about it in the Remarks section of the link you posted.
You can set the process priority using SetPriorityClass.
Now that we got the technicalities out of the way, I find little use for manipulating the priority of a thread directly. The OS scheduler is sophisticated enough to boost the priority of threads blocked in I/O over threads doing CPU computations (to the point that an I/O thread will preempt a CPU thread when the I/O interrupt arrives). In fact, even I/O threads are differentiated, with keyboard I/O threads getting a priority boost over file I/O threads for example.
On Windows, the thread and process priorities are combined using an algorthm that decides overall scheduling priority:
Windows priorities
Pitfalls? Well:
Raising the priority of a thread is likely to give the greatest overall gain if it is usually blocked on IO but must run ASAP afer being signaled by its driver, eg. Video IO that must process buffers quickly.
Raising the priority of threads is likely to have the greatest overall negative impact if they are CPU-bound and raised to a high priority, so preventing the running of normal-priority threads. If taken to extremes, OS threads and utilities like Task Manger will not run.
If a critical section lock is currently owned by a thread and other threads are trying to own this very lock, then all the threads other than the thread which owns the lock enter into a wait queue for the lock to be released.
When the initial owning thread releases the critical section lock then one of the threads in the waiting queue will be selected to run and given the critical section lock allowing the thread to run.
How is the next thread to run selected as it is not guaranteed that the thread that first came will be the owner of the thread.
If threads are not served in FIFO fashion then how is the next owner Thread selected from the wait queue?
The next thread to get the critical section is chosen non-deterministically. The only thing that you should be concerned about is whether the critical section is implemented fairly, i.e., that no thread waits infinitely long to get its turn. If you need to run threads in specific order, you have to implement this yourself.
The next thread is chosen in quasi FIFO order. However many system level variables may cause this to appear non deterministic:
From Concurrent Programming On Windows by Joe Duffy: (Chapter 5)
... When a fixed number of threads
needs to be awakened, the OS uses a
semi-fair algorithm to choose between
them: as threads wait they are placed
in a FIFO queue that the awakening
logic consults when determining which
thread to wake up. Threads that have
been waiting for the longest time are
thus preferred over threads that been
waiting less time. Although the OS
does use a strict FIFO data structure
to manage wait lists; ... this
ordering is regularly perturbed by
other system code and is not reliable.
Posix threads do the FIFO queue.
What about Thread Scheduling Algorithm , the threads in waiting state get priority as per Thread Scheduling algorithm
Plz correct if I am wrong.