Skip to content

Wrong sequence Destructor / Constructor and task is not processed #27

Description

@CyrilleBenard

Hi there,

I'm trying to use this thread-pool "LIB" and before using it, I wanted to make some stress tests on it to identify its limit, its hardening and reliability.

I wrote a really short main function and set a small amount of thread (1) with also a small file queue size (2). The behavior I can see is really strange : Some destructor may be called before constructor :huh: and the same input may be treated by several tasks

Here is the small main.cpp :

#include <iostream>
#include <regex>

#include <vector>
#include <signal.h>
#include <unistd.h>
// #include "logger.h"

#include <future>
#include <utility>

#include "thread_pool.hpp"

static volatile bool         g_theEnd = false ;

#define DEBUG(...)   { printf(__VA_ARGS__) ; printf("\n") ; }
#define INFO(...)    { printf(__VA_ARGS__) ; printf("\n") ; }
#define WARNING(...) { printf(__VA_ARGS__) ; printf("\n") ; }
#define ERROR(...)   { printf(__VA_ARGS__) ; printf("\n") ; }

#define LOG_INIT(a)
#define SET_LOG_LEVEL(a)
#define LOG_END()

//
//
//
void cleanup(void)
{
    // Ask the threads to give up
    g_theEnd = true ;

    INFO("Stop test-thread-pool") ;
    LOG_END() ;
}

//
//
//
class NgapMessageDecode
{
public:
    NgapMessageDecode(int fd) : m_fd(fd)
    {
        DEBUG("Constructor %.8ld, fd=%.2d", this, fd) ;
    }

    virtual ~NgapMessageDecode()
    {
        DEBUG("Destructor  %.8ld, fd=%.2d", this, m_fd) ;
    }

    void operator()()
    {
        DEBUG("Decode %.2d, this=%ld, thread=%.8ld", m_fd, this, pthread_self()) ;
        // sleep(1) ;
    }

private:
    // std::promise<void> *    m_waiter ;
    int                     m_fd ;
};


int main(int argc, char * argv[])
{
    LOG_INIT("test-thread-pool") ;
    SET_LOG_LEVEL(_LOG_DEBUG) ;

    INFO("%s", "") ;
    INFO("Start test-thread-pool") ;

    tp::ThreadPoolOptions   threadPoolOption ;

    threadPoolOption.setThreadCount(1) ;
    threadPoolOption.setQueueSize(2) ;

    tp::ThreadPool  threadPool(threadPoolOption);

    for(int i=0; i<100; i++)
    {
        try
        {
            threadPool.post(NgapMessageDecode(i)) ;
        }
        catch(std::runtime_error & e)
        {
            std::cout << e.what() << std::endl ;
        }
    }
    sleep(1) ;
    cleanup() ;
    return 0 ;
}

The output is :

Start test-thread-pool
Constructor 140734462742560, fd=00
Destructor  140734462742176, fd=00
Destructor  140734462742560, fd=00
Constructor 140734462742560, fd=01
Destructor  140734462742176, fd=01
Destructor  140734462742560, fd=01
Constructor 140734462742560, fd=02
Destructor  140734462742560, fd=02
thread pool queue is full
Constructor 140734462742560, fd=03
Destructor  140734462742560, fd=03
thread pool queue is full
Constructor 140734462742560, fd=04
Destructor  140734462742560, fd=04
thread pool queue is full

How can the Destructor 140734462742176, fd=00 (line2) can be called before the constructor ?

More over, this same Destructor refers to the object where fd==00 whereas the corresponding constructor below refers to fd==01

Thus, how can I got the sequence described in the 3 first lines : Constructor / Destructor / Destructor with the same FD==00

So, I probably missed something or at least misunderstood how I'm supposed to use this "LIB" but I can't find out what's the good practice :/

Branch used : master
I can't use the branch round-robin-stealing 'cause it refers to std::exchange that is defined in C++14 and I must stay in C++11

Command to build the main application listed above, to facilitate :

g++ -c   -DLOG -I<path_to_thread-pool-cpp>/include/thread_pool -Wall -Wextra -g -std=c++11 -o main.o main.cpp

g++ -g   -o test-thread-pool main.o -lpthread

All kind of help would be appreciated 👍

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions