Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

A Sketch for a Generic Queue - Multithreading Made Easy

4.87/5 (10 votes)
21 Apr 2014CPOL4 min read 23K  
Sktech for a generic queue which can handle tasks, process them and report the result

Contents

  1. Introduction
  2. Background
  3. Difficulties
  4. Points of Interest

Introduction

This tip shows you how a generic queuing system could work. The basic idea behind this queuing system is to make multi-threading as easy as possible and take a bit of its burden from a developers' back.

A generic queuing system can be useful if you have several time-consuming operations (running at the same time) which should be executed in the background while the user should continue working or wait for the end of the operation without the UI thread become frozen. It also helps you to take multi-threading code out from the GUI code and classes at all.

Background

This approach uses a FIFO / Round-Robin based queuing mechanism.

FIFO stands for First in - First out which basically means that all tasks in a queue are processed in the order in which they were added to the queue. Round-Robin means that you have one queue, containing multiple lists of tasks and the tasks in the lists are processed list by list, picking one task to process from each list.

Image 1

Example of a Round-Robin queue

A usual round-robin queue has the benefit that it can easily be used for weighted-fair queuing. Weighted-fair queuing describes a queue which automatically decides which task is processed next according to a tasks waiting time in the queue.

Image 2

Example of a round-robin queue with multiple task processing units

I decided to use a FIFO / Round-Robin based approach to process the task weighted-fair and as fast as possible.
This is why my final approach for my queuing system looks like this:

Image 3

A generic and dynamic queuing system - the final approach

In my approach, I have a class called QueueManager which is protecting the whole Queuing mechanism and provides the functionality of adding tasks (which will be stored and passed into the QueueManager in the QueueObject class) to the Queue. The QueueManager does assign the tasks to a Queue. It is possible to have multiple Queues managed by the same QueueManager, the assignment happens automatically.

Every queue has multiple QueueLists in which the tasks coming from the QueueManager will be stored until one of the Queues' QueueHandlers takes them from the list and processes them. A QueueObject is processed by the QueueHandler using the function pointer of the QueueObject. The result of the processed operation is also returned by a function pointer to another (or perhaps the same) function.

Difficulties

As in every project, there are some very nasty difficulties I will be facing during the implementation. I listed some of the most outstanding ones here:

Even though there is a template std::function available with C++ 11 there are no delegates in previous versions of the C++ language. Just function pointers. I am pretty disappointed that there is no possibility to use function pointers to get something like a delegate. At the moment I am rather undecided between C++ 11's great possibilities (which may lead to one or another compiler glitch) or doing it all myself, but especially the new great multithreading capabilities of C++ 11 may require it to switch to the fancy side - Apart from C++ 11's std::thread class there are in fact nearly no platform-independent native C++ compatible multithreading libraries available. Most of them require POSIX and even though I have found a way to make Windows POSIX-compatible I don't really trust this way to solve this because it requires a third-party patch. Another approach would be to use the Qt Framework by Digia - I'll have to decide whether I am going to use Qt or go for the C++ 11 std:thread class.

Points of Interest

This example showed me what a powerful language C++ really is. Honestly, I was most surprised when I found out about the function pointers available in native C++. If implemented properly, this kind of queuing system will take a huge burden from a developers back. Furthermore, many people about there don't seem to know about the huge multithreading capabilities coming up with C++ 11, and an implementation of the scripted queuing system would probably cover a lot of needs and maybe even provide great learning materials for those who want to know about C++ 11 and multithreading technologies coming up with it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)