Giter Club home page Giter Club logo

multi-threaded-queue's Introduction

Description

This project is a multi-threaded queue for storing a finite number of elements using a lock-free circular buffered queue.

Implemented functionalities:

  • Storage; essential pop and push operations.
  • Reading thread blocks if the queue is empty.
  • Writing thread blocks if the queue is full.
  • Reading and writing threads block for a set amount of time. Functions return a boolean indicating the success of the operation.
  • The project does not use std::queue but instead a circular buffer.
  • The project does not use std::mutex but instead atomic operations.
  • Documented using Doxygen.
  • Includes tests in googletest.
  • Uses CMake for building.

Requirements:

The following table list the tools and respective versions used during the development of this project. Other versions probably will work as well, but they haven't been tested.

Purpose Tool name Version
Build Generator Cmake 3.24.2
Compiler g++ 12.2.0
Documentation Doxygen 1.9.3
Test Suite googletest 1.12.1

Note: googletest should be automatically downloaded by CMake and not require an external download.

Building:

From the directory that contains the CMakeLists.txt, run the following commands:

  • $ cmake -G 'Unix Makefiles' -S . -B build
  • $ cd build && make

Documentation

The project uses the Doxygen style documentation and includes a Doxyfile for aiding. We can generate the documentation using the following command in the root directory:

  • doxygen Doxyfile

Unit tests:

From within the build directory, run the command:

  • $ ./test_pairs

Note:

Sometimes the tests will fail not because of the logic of the functions but because the push and pop operations have a timeout behaviour. As such, it isn't easy to assert the expected behaviour correctly.

We calculate the worst possible outcome and compare it with the test's execution as a workaround. We then see if it is within an acceptable margin of error. We can change this margin by editing the acceptableMargin variable in file /tests/single.cpp, which, for now, is set to a 2% margin of error.

One possibility would be to increase the number of tries before giving up, which quickly raises the test times. Another possibility was to wrap the timeout portions of the code with a preprocessor macro that could be toggled during compilations. This approach wasn't used because CMake does not support multiple configurations per project when using 'Unix Makefiles' and these were prefered as they simplify requirements for using the project.

Design Choices:

Because I want to reuse this code in other projects, the design of the container was affected by a few personal decisions:

  • I wanted to avoid a container that used mutexes to implement multithreading. We based the project's design on the UniQ Multithreading Libray, which implements a lock-free circular buffered queue, with a few modifications of my own.
  • I wanted to avoid memory allocations; as such, the container uses a compile-time constant for dictating its storage size. My uses don't require a resizeable container, so this approach should reduce memory consumption as the container can reside in a stack variable.
  • The container's capacity has to be a power of 2. This constraint helps to ensure the internal indexes' values are always below the storage's capacity, and this method simplifies the implementation.

Possible improvements:

  • Using std::optional for each storage element: The issue was distinguishing whether the storage was empty or full when the insert and extract indexes held the same value. The implemented solution was to use an optional to validate if each element does, in fact, exist. The issue is that it creates an additional overhead that scales with the size of the container.
    • An alternative could be to use a boolean that registers if the container is full when the insertion index catches up to the removal index. We did not do this to simplify the code and avoid more checks.

multi-threaded-queue's People

Contributors

miguelpedrosa avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.