If I have a process whose all threads are running on different cores, what will sched_yield do in that case? Get relinquished and immediately issued again? Because what I see is that sched_yield does not cause the thread calling it, wait any cycles at all, it seems that the call is not even going to the kernel.
As far as the linux kernel is concern, one core is one CPU, so sched_yield would causes the calling thread to relinquish the CPU but if the thread is the only one in the queue, it won't wait any cycle.
So yes in your case sched_yield would immediatly return immediatly if there are no thread waiting on the current core.
Note that sched_yield is not designed to control how threads are run on multiple CPU.
The man page says:
If the calling thread is the only thread in the highest priority
list at that time, it will continue to run after a call to sched_yield().
So if there's nothing more important to run, the function will basically do nothing.
Related
I am trying to achieve the following:
Force the newly created thread to start running, immediately after pthread_create(). No real-time scheduling is being used.
From the pthread_create() man page:
Unless real-time scheduling policies
are being employed, after a call to pthread_create(), it is
indeterminate which thread—the caller or the new thread—will next
execute.
Which of course makes sense. Thus, I thought by using pthread_yield() I would force the newly created thread to take over and as a result start. But this is not the case.
I could only achieve the desired result by sleeping after the pthread_create(). But I don't want to rely on this solution atm.
Why can't I achieve my goal with pthread_yield()?
Is there some other way than using sleep?
The creation of new threads is handled the same way as task-switching, i.e. follows the scheduling policy? For example, in RT (preemptive) scheduling, if the newly created thread has a higher priority, will it immediately preempt the current thread?
Related post:
Does pthread_create starting thread?
pthread_mutex not updating fast enough, so one thread "hogs" the lock.
Thanks!
If you are on a multi-core system, then it is possible that your new thread is scheduled on a core different from the thread that created it. Calling pthread_yield() may not have the desired effect, since it may only affect scheduling on the core of the caller, and not any other core. The effect is usually placing the thread at the end of runnable queue. (It is also noteworthy that pthread_yield() is not a standard system call, so there is no standard reference regarding its intended behavior.)
Calling sleep() may yield a different result if the sleep time is non-zero. The thread is actually placed in a timer wake-up queue, and must be moved back to the runnable queue after the timer expires. This will make it more likely that a new thread on a different core will run before the creating thread wakes back up.
If a new thread has a higher priority than the thread that created it, it will preempt the creating thread.
As recommended in the comments, predictable behavior can be achieved by making the creating thread conditionally wait on a signal from the newly created thread.
I want to yield a multithreaded process in Linux. I know a thread can be yielded by calling sched_yield. I guess, on the other hand, the whole process can be yielded by calling sleep(0), since sleep works at process level. Am I right?
sched_yield will yield the thread that is currently running, relinquishing the rest of its timeslice. The processor then context switches to the next thread. Whether that thread is another which belongs to your process is unknown. It could be, it might not be.
To yield the whole process you would therefore need to yield each thread that existed in that process. sleep works similarly. It will sleep for that particular thread, not the whole process.
Wrong.
sleep(3)
sleep() makes the calling thread sleep until seconds seconds have
elapsed or a signal arrives which is not ignored.
EDIT
From the comments I see people use an outdated site for the manual pages. Stop using that site, use the kernel.org pages which should be up-to-date.
I have to develop an application that tries to emulate the executing flow of an embedded target. This target has 2 levels of priority : the highest one being preemptive on the lowest one. The low priority level is managed with a round-robin scheduler which gives 1ms of execution to each thread in turn.
My goal is to write a library that provide the thread_create, thread_start, and all the system calls that are available on my target and use POSIX functions to reproduce the behavior natively on a standard PC.
Thus, when an high priority thread executes, low priority threads should be suspended whatever they are doing at that very moment. It is to the responsibility of the low priority thread's implementation to ensure that it won't be perturbed.
I now it is usually unsafe to suspend a thread, which explains why I didn't find any "suspend(pid)" function.
I basically imagine two solutions to the problem :
-find a way to suspend the low priority threads when a high priority thread starts (and resume them when there is no more high priority activity)
-periodically call a very small "suspend_if_necessary" function everywhere in my low-priority code, and whenever an high priority must start, wait for all low-priority process to call that function and be suspended, execute as single high priority thread, then resume them all.
Even if it is not-so-clean, I quite like the second solution, but still have one problem : how to call the function everywhere without changing all my code?
I wonder if there is an easy way to doing that, somewhat like debugging code does : add a hook call at every line executed that checks for a flag and run some specific code when that flag changes?
I'd be very happy if there is an easy solution to that problem, since I really need to be representative with the behavior of the target execution flow...
Thanks in advance,
Goulou.
Unfortunately, it's not really possible to implement what you want with true threads - even if the high prio thread is restarted, it can take arbitrarily long before the high prio thread is scheduled back in and goes to suspend all the low priority threads. Moreover, there is no reliable way to determine whether the high priority thread is blocked or not using only POSIX threads; you could try tracking things manually, but this runs the risk of both false positives (the thread's blocked on something, but the low prio threads think it's running and suspend itself) and false negatives (you miss a resumed annotation, or there's lag between when the thread's actually resumed and when it marks itself as running).
If you want to implement a thread priority system with pure POSIX, one option is to not use threads, but rather use setcontext for cooperative multitasking. This would allow you to swap between threads at a user level. However you must explicitly yield the CPU in this case. It also doesn't help with blocking syscalls, which would then block all threads in your app; but since you're writing an emulator this might not be an issue.
You may also be able to swap threads using setcontext within a signal handler; I've not tested this case myself, but it could be worth a try scheduling using setcontext in a SIGALRM handler.
To suspend a thread, you sleep it. If you want to be able to wake it on command, sleep it using sigwait, which puts the thread to sleep until it gets a signal. You can send a specific thread a signal with pthread_kill (crazy name, but it actually just sends signals to a thread). This is a very fast way to sleep and wake up threads. 40x Faster than condition variables and very easy.
Looks like linux doesnt implement pthread_suspend and continue, but I really need em.
I have tried cond_wait, but it is too slow. The work being threaded mostly executes in 50us but occasionally executes upwards of 500ms. The problem with cond_wait is two-fold. The mutex locking is taking comparable times to the micro second executions and I don't need locking. Second, I have many worker threads and I don't really want to make N condition variables when they need to be woken up.
I know exactly which thread is waiting for which work and could just pthread_continue that thread. A thread knows when there is no more work and can easily pthread_suspend itself. This would use no locking, avoid the stampede, and be faster. Problem is....no pthread_suspend or _continue.
Any ideas?
Make the thread wait for a specific signal.
Use pthread_sigmask and sigwait.
Have the threads block on a pipe read. Then dispatch the data through the pipe. The threads will awaken as a result of the arrival of the data they need to process. If the data is very large, just send a pointer through the pipe.
If specific data needs to go to specific threads you need one pipe per thread. If any thread can process any data, then all threads can block on the same pipe and they will awaken round robin.
It seems to me that such a solution (that is, using "pthread_suspend" and "pthread_continue") is inevitably racy.
An arbitrary amount of time can elapse between the worker thread finishing work and deciding to suspend itself, and the suspend actually happening. If the main thread decides during that time that that worker thread should be working again, the "continue" will have no effect and the worker thread will suspend itself regardless.
(Note that this doesn't apply to methods of suspending that allow the "continue" to be queued, like the sigwait() and read() methods mentioned in other answers).
May be try an option of pthread_cancel but be careful if any locks to be released,Read the man page to identify cancel state
Why do you care which thread does the work? It sounds like you designed yourself into a corner and now you need a trick to get yourself out of it. If you let whatever thread happened to already be running do the work, you wouldn't need this trick, and you would need fewer context switches as well.
I spent a good long while looking for info on the differences between time.h::sleep() and pthread.h::pthread_yield() but was unable to find any solid reference material and so I am posting this question.
What is the difference between time.h::sleep() and pthread.h::pthread_yield()?
Update:
The reason I ask is because I was using sleep() to sleep() each individual thread... and my application started having issues when there was 8 threads vs 4 threads. When I went online to see if sleep() only affects each thread, I couldn't find any good reference stating whether Sleep() affects the entire process OR sleep() only affects the individual thread.
From pthread_yield:
The pthread_yield subroutine forces the calling thread to relinquish use of its processor, and to wait in the run queue before it is scheduled again. If the run queue is empty when the pthread_yield subroutine is called, the calling thread is immediately rescheduled.
From the sleep manpage:
sleep() makes the calling process sleep until seconds seconds have elapsed or a signal arrives which is not ignored.
If you don't want to have a real time delay in your threads and just want to allow other threads to do their work, then pthread_yield is better suited than sleep.
sleep() causes your program to stop executing for a certain length of time. No matter what else happens on the system, your thread will not start again until at least the length of time passed to sleep() has elapsed. pthread_yield() notifies the operating system that your thread is done working, and that it can switch execution to another thread. However, if there is no higher-priority thread that needs to do work at that time, your thread may start again immediately.
IOWs, after sleep() your thread is guaranteed to stop running even if no one else needs to run, while pthread_yield() is just a polite way to give other threads a chance to run if they need to.
Update in response to question update: both sleep() and pthread_yield() affect only the calling thread.
sleep(s) takes the current thread of execution and suspends it until s seconds have passed (or it is woken up by a signal.)
In more practical terms, when you call sleep(), that thread will cease execution and just... wait until the specified time has passed. Once it passes, that thread is placed into the ready queue.
pthread_yield() says "take this thread, and put it into the ready queue." Your thread will stop execution and be in the 'waiting' state to be selected/run by the scheduler. This does not gaurantee that your thread will not immediately resume running. But it gives another thread a chance to run at a given point in its execution.
I am going to go out on a limb and say that sleep(0) would accomplish the same thing as a pthread_yield() - both stopping execution and placing the thread in the ready queue.