Skip to content

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

@CyrilleBenard

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 👍

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