1

I have four threads which has its own private queue and a private'int count' member, whenever a task is produced from the program thread, it should be enqueued to a thread's queue which has minimum 'int count' among the threads.

whenever a task is pushed into the queue, the private 'int count' should be increased by 1 whenever a task is popped out of the queue, the private 'int count' should be decreased by 1

so, the 'int count' is dynamically changing regarding to tasks push,pop operation and the program thread will dispatch the task to the queue with the lowest, (or first zero found), count.

This is the underlying logic of the program.

I am working in c++ programing language in linux multithreading library implementing a multi-rate synchronous data flow paradigm.

could you please give some coding ideas for implemenating this logic. ie. 1.Initializing all private int queue counter =0

2.counter++ when task are pushed,

3.counter-- when tasks are popped,

4.Task disptacher sees the private int count of each thread.

5.Dispatches tasks to queue which has minimum count

aram
  • 71
  • 1
  • 10
  • Is this homework? No problem if it is, just wondering what level of detail you need? – Caribou Jan 09 '13 at 13:31
  • @Caribou i need some logics like which loops, or functions should be used to increment and decrement the counter when some tasks are pushed or popped in a queue – aram Jan 09 '13 at 13:40
  • Is more research and information needed for the question? pls let me know – aram Jan 09 '13 at 13:46
  • just considering the answer now - there are some subtleties because of what you want to do... – Caribou Jan 09 '13 at 13:56
  • yes, i will ask the question again with some more research . – aram Jan 09 '13 at 14:00

1 Answers1

2

I have four threads which has its own private queue and a private'int *count' member, whenever a task is produced from the program thread, i*t should be enqueued to a thread's queue which has minimum 'int count' *among the threads.*

whenever a task is pushed into the queue, the private 'int count' *should be increased by 1 whenever a task is popped out of the queue,* the private 'int count' should be decreased by 1

Ok, so Basically your program thread is the producer and you have 4 consumer threads. By using a queue in each thread you will be minimizing the time spent by the main thread interacting with the consumers. N.B. You need to consider whether your threads are going to be starved / or overflow - I.E. if the single producer will create "work" at a rate that warrants 4 consumers, or if 4 consumers will be swamped.

naive approach So you need to synchronize the queue access / increment meaning that you need a mutex to stop the consumer accessing anything while the count and queue are modified. The easiest way is to do the synchronization would be to have a method (E.G. enqueue(Item& item) ) which locks the mutex within it.

C++11 : Mutex http://en.cppreference.com/w/cpp/thread/mutex

Additionally if starvation is an issue (or overflow) you will need to use some signalling to stop the relevant threads activity (Starved - stop consumers to avoid CPU usage, Overflow - stop producer while consumers catch up). Usually these signals are implemented using condition variables.

C++11 : Condition variables : http://en.cppreference.com/w/cpp/thread/condition_variable

so, the 'int count' is dynamically changing regarding to tasks *push,pop operation and the program thread will dispatch the task t*o the queue with the lowest, (or first zero found), count.

So the situation is slightly complicated here, in that the threads that you want to populate will be the ones with the least work to do. This requires that you inspect the 4 counts and choose the queue. However because there is only one producer you can probably just scan for the queue without locking. The logic here is that the consumers will not be affected by the read, and the choice of thread would not really be incorrect even with the consumers working during that choice.

So I would have an array of thread objects, each of which would have the count, and a mutex for locking.

1.Initializing all private int queue counter =0

Initialize the counts in the constructors - make sure that the producer isn't working during initialization and synchronization won't be an issue.

2.counter++ when task are pushed, *3.counter-- when tasks are popped,*

Implement 2 methods on the thread object to do the enqueing / dequeuing and in each use a lock_guard to lock the mutex (RAII technique). Then push/pop item to/from the queue and increment/decrement as applicable.

C++11: lock_guard http://en.cppreference.com/w/cpp/thread/lock_guard

4.Task disptacher sees the private int count of each thread. *5.Dispatches tasks to queue which has minimum count*

As I said above if there is only one you can simply scan through the array of objects and choose (maintain an index to) the thread object where the counter (add a getCount() method)is the lowest. It will most likely be the lowest even with the consumers continuing their work.

If there are multiple threads producing work then you might need to think about how you want to handle the 2 threads enquing to the same thread (It might not matter)

Caribou
  • 2,070
  • 13
  • 29
  • @CaribouThank you,So the overall idea would be Create a array of thread ojects with constructor having the count and a mutex for locking. correct? – aram Jan 10 '13 at 09:44
  • yep - just remember my solution above is based on a single producer and if you increase that number you'll need to think about how they interact - if both choose the same queue for example. – Caribou Jan 10 '13 at 09:51
  • @CaribouThe new jobs are not produced by the program thread(sorry i mentioned wrong)everytime, as i use multi-rate synchronous data flow paradigm, the jobs are produced by the graphs and nodes. All the jobs produced from the graphs and nodes should search the minimum local queues and enqueue in it. so will there be a change in steps of implemenation you explained above when i use the jobs from graphs and nodes instead from program threads. – aram Jan 10 '13 at 15:09
  • http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=1458143&url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel5%2F5%2F31377%2F01458143Is this the kind of thing you are doing? (in the same ballpark?) – Caribou Jan 10 '13 at 15:16
  • yes this is the kind i am doing. Multi-rate synchronous data flow paradigm – aram Jan 10 '13 at 15:20
  • The *basic* idea will be the same, certainly in C++11 you'll use the same classes and calls. The processing threads can still be held in the array, but with multiple writers you may get contention/locking. I would say build it then improve it. **BUT** this is a very complex domain and it appears to me that you would do well to find a senior programmer / lecturer (?) who could help you define what you need to do specifically. It's going to be beyond me to give you a definite solution without investigating the domain properly (I'm sorry I can't do any more than I have) - – Caribou Jan 10 '13 at 15:23
  • @Caribouplease dont be sorry, i got a basic idea now, as you said bulid and then improve. I will first try to build a logical flow of code basically and i can go think and do it domain specific.i hope i can ask you doubts when building the basic logical code flow of the idea. Thank you – aram Jan 10 '13 at 15:35