4

Suppose I have a multi-threaded program in C++11, in which each thread controls the behavior of something displayed to the user.

I want to ensure that for every time period T during which one of the threads of the given program have run, each thread gets a chance to execute for at least time t, so that the display looks as if all threads are executing simultaneously. The idea is to have a mechanism for round robin scheduling with time sharing based on some information stored in the thread, forcing a thread to wait after its time slice is over, instead of relying on the operating system scheduler.

Preferably, I would also like to ensure that each thread is scheduled in real time.

In case there is no way other than relying on the operating system, is there any solution for Linux?

Is it possible to do this? How?

GoodDeeds
  • 7,956
  • 5
  • 34
  • 61

2 Answers2

5

No that's not cross-platform possible with C++11 threads. How often and how long a thread is called isn't up to the application. It's up to the operating system you're using.


However, there are still functions with which you can flag the os that a special thread/process is really important and so you can influence this time fuzzy for your purposes.

You can acquire the platform dependent thread handle to use OS functions.

native_handle_type    std::thread::native_handle //(since C++11)

Returns the implementation defined underlying thread handle.

I just want to claim again, this requires a implementation which is different for each platform!


Microsoft Windows

According to the Microsoft documentation:

SetThreadPriority function

Sets the priority value for the specified thread. This value, together with the priority class of the thread's process determines the thread's base priority level.


Linux/Unix

For Linux things are more difficult because there are different systems how threads can be scheduled. Under Microsoft Windows it's using a priority system but on Linux this doesn't seem to be the default scheduling.

For more information, please take a look on this stackoverflow question(Should be the same for std::thread because of this).

Community
  • 1
  • 1
realvictorprm
  • 614
  • 6
  • 20
  • Thank you. In that case, is there a way to flag the os in Linux? – GoodDeeds Jan 07 '17 at 17:01
  • Thank you. However, that link deals with pthreads, whereas I am interested in C++11 threads – GoodDeeds Jan 07 '17 at 17:07
  • 1
    Indeed that's true but on Linux system `std::thread` should be a pthread. – realvictorprm Jan 07 '17 at 17:13
  • @ArthurM. - well, "should", maybe, but it's not required to be a pthread. The actual requirement is that whether `native_handle()` exists is implementation defined, and if it does exist, what you can do with the result is implementation defined. So there's nothing portable here, even for programs compiled with different compilers targeting the same operating system. – Pete Becker Jan 07 '17 at 17:36
  • @Peter Becker According to the specifications of C++11 a native handle exists always. And yes I do know and I said too, this handle is different for each platform. However, the point about how things are for Linux actually does not depend on pthread. The link shows that it depends on the current thread scheduling of the Linux system. PS, for that case I said that `std::thread` **_should_ be a pthread** under Linux. – realvictorprm Jan 07 '17 at 17:47
1

I want to ensure that for every time period T during which one of the threads of the given program have run, each thread gets a chance to execute for at least time t, so that the display looks as if all threads are executing simultaneously.

You are using threads to make it seem as though different tasks are executing simultaneously. That is not recommended for the reasons stated in Arthur's answer, to which I really can't add anything.

If instead of having long living threads each doing its own task you can have a single queue of tasks that can be executed without mutual exclusion - you can have a queue of tasks and a thread pool dequeuing and executing tasks.

If you cannot, you might want to look into wait free data structures and algorithms. In a wait free algorithm/data structure, every thread is guaranteed to complete its work in a finite (and even specified) number of steps. I can recommend the book The Art of Multiprocessor Programming where this topic is discussed in length. The gist of it is: every lock free algorithm/data structure can be modified to be wait free by adding communication between threads over which a thread that's about to do work makes sure that no other thread is starved/stalled. Basically, prefer fairness over total throughput of all threads. In my experience this is usually not a good compromise.

ytoledano
  • 3,003
  • 2
  • 24
  • 39
  • Thank you. I did not understand `If instead of having long living threads each doing its own task you can have a single queue of tasks that can be executed without mutual exclusion - you can have a queue of tasks and a thread pool dequeuing and executing tasks.` Could you please elaborate? – GoodDeeds Jan 08 '17 at 08:03
  • 1
    You say you want it to appear to the user as if tasks happening at the same time. For that, you have threads executing those tasks. But that's not the only way to achieve this. Instead, you can have your tasks in a single queue and have threads dequing work and doing it. Then, to make sure that it appears as though things happen at the same time you need to: 1. make sure tasks don't take too long to finish. 2. have enough threads executing tasks. 3. that tasks can be accomplished without mutual exclusion - meaning without locks that halt other threads waiting to acquire the locks. – ytoledano Jan 08 '17 at 08:59