3

While developing a VoIP based application, we have a common multi-threaded C++11 module. It works fine in iOS, MacOS but finds thread scheduling difficulty in Android.

Optional Design Description (only if interested)

I have few threads running with message queues.

  1. Master (writes data to sockets which is received in SSL_Read queue)
  2. SSL_Read (reads data from SSL and updates in its queue)
  3. SSL_Write (writes data to SSL which is received directly from Socket threads)
  4. Thread per Socket (reads data from socket and send to SSL_Write queue)

1-2 are related and 3-4 are related.
I have observed that during many calls, only 2 threads are actively running and other 2 threads don't get running time. Due to which 1 way voice path is observed.

Problem

I doubted this as an Android Linux issue and for that, I have an unanswered post already:
c++11 multithreading issues with Android where some threads are not scheduled properly.
Went through std::this_thread::yield() usage?

The goal is to give similar time slicing to all threads. Tried following options:

  1. I decided to use std::thread::yield() when the message queue is filled up beyond certain limit; e.g. 10 messages from 1 thread. I tried yield() 1 time and 100 time in loop, but there is no advantage of it. The same thread continue running.
  2. Same thing for sleep_for() option with 0 and 100 ms. Same thread keep running.
  3. Tried changing nice() value to -10, -20 for all threads but no luck.

How to use std::this_thread::yield() effectively without burning out too many CPU cycles?

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Why are you using yield() instead of normal inter-thread comms mechanisms like condvars/semaphores? – Martin James Dec 15 '14 at 17:51
  • @MartinJames, the `std::mutex` with `notify_all()` is already used. Despite that I am seeing such behavior every alternate time. – iammilind Dec 15 '14 at 18:32

1 Answers1

5

It is legal for std::this_thread::yield() to do absolutely nothing. It provides an opportunity for the scheduler to schedule another thread; the scheduler doesn't have to take advantage of it.

You could try either:

  1. Having each thread able to process whatever work needs doing, by packaging the work into a generic task queue. That way it doesn't matter which thread takes the work, the most important work gets done when there is a thread to do it.

  2. Adding synchronization between the threads such as a barrier mechanism (see e.g. boost's barrier class) to keep all 4 threads in sync.

Anthony Williams
  • 66,628
  • 14
  • 133
  • 155