Ciao a tutti ho un problema, o meglio vorrei un chiarimento su server con un thread che gestisce le connessioni.
La mia classe server è fatta così:
server.h
codice:
class Server
{
public:

    /**
    *\brief Costruttore della classe
    */
    Server ();
    /**
    *\brief Distruttore della classe
    */
    virtual ~Server();
    /**
    *\brief Metodo che fa partire il server
    */
    void Start();
    /**
    *\brief Metodo che ferma il server
    */
    void Stop();
    /**
    *\brief Metodo che imposta il segnale di spegnimento del server e attende il completamento delle operazioni
    */
    void WaitForCompletation();

private:
    /**
    *\brief Metodo che implementa la routine del server e lo pone in ascolto sulla porta specificata nel file di configurazione
    */
    void Run ();
    /**
    *\brief Metodo che viene richiamato nel caso di una nuova connessione sul server principale e gestisce le richieste.
    */
    void serviceRoutine(Socket * sock);

private:
    Centrale * centrale;
//    unsigned char pacchetto[512];
//    unsigned char recvBuffer[512];
    Database * db_epro;
    Parametri * param;
    Logger * log;
    Socket serversock;
    thread mainthread;
    thread thread_serventi[10];
    int n_thread;
    bool thread_stop;
};

#endif // SERVER_H
server.cpp
codice:
Server::Server()
{
#if (DEBUGSERVER >=2)
    cout<<"Chiamato costruttore della classe server\n";
#endif

    Server::param = new Parametri(FILEPARAM);
#if (DEBUGSERVERs >=2)
    cout<<"Chiamato new Parametri\n";
#endif
    Server::db_epro = new Database(param->getParametro(DATABASE),         //Nome db
                                   param->getParametro(IP_DB),            //IP del db
                                   param->getParametro(PORT_DB),          //Porta del db
                                   param->getParametro(USER_DB),          //Nome utente
                                   param->getParametro(PASSWD_DB));       //Password di accesso
    Server::log = new Logger(param->getParametro(FILELOG),param->getParametro(PATHLOG));

    n_thread = 0;
}

Server::~Server()
{
    cout<<"Distruttore del server\n";
    delete param;
    delete db_epro;
    delete log;
}

void Server::WaitForCompletation()
{
    Server::Stop();
    for (int i = 0; i<n_thread; i++)
    {
        thread_serventi[i].join();
    }
    mainthread.join();
}

void Server::Stop()
{
    thread_stop = true;
}

void Server::Start()
{
    for(int i = 0 ; i< n_thread; i++)
    {
        thread_serventi[i].join();
    }
    mainthread = std::move(std::thread(&Server::Run,this));
    thread_stop = false;
}

void Server::Run()
{
    Socket serversock;
    Socket new_sock;
    stringstream Stream;

    if(!serversock.create())
    {
        throw SocketException ("Could not create client socket.");
        return;
    }
    cout<< "Creazione avvenuta con successo\n";
    if(!serversock.bind(atol(param->getParametro(PORTASCOLTO).c_str())))
    {
        throw SocketException ( "Could not bind to port." );
        return;
    }
    cout<< "Binding OK!!!\n";

    if ( ! serversock.listen() )
    {
        throw SocketException ( "Could not listen to socket." );
    }
    cout<< "Listening OK!!!\n";

    serversock.set_non_blocking(true);
    while(!thread_stop)
    {
        serversock.accept(new_sock);
        if (new_sock.is_valid())
        {
            cout<<"Ricevuta connessione\n";
            thread_serventi[n_thread] = move(thread(&Server::serviceRoutine,this,&new_sock));
            n_thread++;
        }
    }
    cout<<"Fermato thread principale del server\n";
    return;

}

void Server::serviceRoutine(Socket * sock)
{
    unsigned char recvBuff[512];
    unsigned char pacchettoinv[512];
    Centrale * centrale = NULL;
    int start = 0;
    int len = 0;
    short crc = 0XFFFF;
    long codice = 0;
    stringstream Stream;
    int nelem;
    int n;

    string query;
    PGresult * res;

    sock->set_non_blocking(false);

    while(!thread_stop)
    {
        memset(recvBuff,'\0',512);
        start = 0;
        ///Ricezione del pacchetto
        n = sock->recv(recvBuff);
        cout<<"Ricevuto pacchetto\n";

        ///Trovo il byte iniziale in caso il buffer sia sporco
        while((recvBuff[start]!= 0x0A) && (start <n))
        {
            start++;
        }

        if (n<=0)
        {
            break;;
        }
        else
        {
            printf("Il valore 0x0A si trova in posizione %d\n", start);
            len = recvBuff[start+1];

            crc = (recvBuff[start+len+3]&0xFF)+((recvBuff[start+len+4]&0xFF)<<8);

            ///Controllo che il pacchetto sia corretto.
            if ((crc&0xFFFF) == Crc_16(&recvBuff[start],len+3))
            {
                ///Individuo il tipo di pacchetto e mi comporto di conseguenza
                switch(recvBuff[start+2])
                {
                case 0x01:///Pacchetto iniziale
                {
                    cout<<"Identificato pacchetto iniziale\n";
                    memset(pacchettoinv,'\0',512);
                    codice = (((recvBuff[start+3]>>4)&0x0F)*100000)+
                             ((recvBuff[start+3]&0x0F)*10000)      +
                             (((recvBuff[start+4]>>4)&0x0F)*1000)  +
                             ((recvBuff[start+4]&0x0F)*100)        +
                             (((recvBuff[start+5]>>4)&0x0F)*10)    +
                             ((recvBuff[start+5]&0x0F)*1)          ;
                    Stream<<codice;
                    query = "SELECT ce_modalita_telegestione FROM centrali WHERE ce_id = '";
                    query.append(Stream.str());
                    query.append("';");
                    res = db_epro->eseguiQuery(query,1);

                    if ((strcmp(PQgetvalue(res,0,0),"TECNOOUT")==0)||(strcmp(PQgetvalue(res,0,0),"TECNO OUT")==0))
                    {
                        centrale = new xxx(codice);
                        //centrale->Start();
                    }///Qui si introdurranno altre centrali
                    else
                    {
                        cout<<"Centrale non valida\n";
                        n_thread--;
                        return;
                    }
                    pacchettoinv[0] = 0x0A;
                    pacchettoinv[1] = 0x00;
                    pacchettoinv[2] = 0x09;
                    crc = Crc_16(pacchettoinv,3);
                    pacchettoinv[3] = crc & 0xFF;
                    pacchettoinv[4] = (crc >> 8) & 0xFF;
                    sock->send(pacchettoinv,5);

                    break;
                }
                case 0x03: ///Richiesta stato della centrale
                {
                    cout<<"Identificato pacchetto richiesta stato centrale\n";
                    memset(pacchettoinv,'\0',512);
                    pacchettoinv[0] = 0x0A;
                    pacchettoinv[1] = 0x01;
                    pacchettoinv[2] = 0x06;
                    pacchettoinv[3] = centrale->getStatoCentrale();
                    crc= Crc_16(pacchettoinv,4);
                    pacchettoinv[4] = crc & 0xFF;
                    pacchettoinv[5] = (crc >> 8) & 0xFF;

                    sock->send(pacchettoinv,6);
                    break;
                }
                case 0x04: ///Richiesta stato della zona
                {
                    cout<<"Identificato pacchetto richiesta stato zona\n";
                    memset(pacchettoinv,'\0',512);
                    nelem=(((recvBuff[start+3]>>4)&0x0F)*1000) +
                          ((recvBuff[start+3]&0x0F)*100)       +
                          (((recvBuff[start+4]>>4)&0x0F)*10)   +
                          ((recvBuff[start+4]&0x0F)*1);
                    pacchettoinv[0] = 0x0A;
                    pacchettoinv[1] = 0x01;
                    pacchettoinv[2] = 0x07;
                    pacchettoinv[3] = centrale->getStatoZone(nelem);
                    crc= Crc_16(pacchettoinv,4);
                    pacchettoinv[4] = crc & 0xFF;
                    pacchettoinv[5] = (crc >> 8) & 0xFF;
                    sock->send(pacchettoinv,6);
                    break;
                }
                case 0x05: ///Richiesta stato della partizione
                {
                    cout<<"Identificato pacchetto richiesta stato partizione\n";
                    memset(pacchettoinv,'\0',512);
                    nelem=(((recvBuff[start+3]>>4)&0x0F)*10) +
                          ((recvBuff[start+3]&0x0F)*1)       ;
                    pacchettoinv[0] = 0x0A;
                    pacchettoinv[1] = 0x01;
                    pacchettoinv[2] = 0x08;
                    pacchettoinv[3] = centrale->getStatoPartizioni(nelem);
                    crc= Crc_16(pacchettoinv,4);
                    pacchettoinv[4] = crc & 0xFF;
                    pacchettoinv[5] = (crc >> 8) & 0xFF;
                    sock->send(pacchettoinv,6);
                    break;
                }
                }
            }
            else
            {
                cout<<"Errore nel CRC\n";
            }
        }
    }
    if (centrale != NULL)
    {
        //centrale->WaitForCompletation();
        delete centrale;
        cout<<"Qui ci arrivo\n";
    }
    sock->chiudi();
    n_thread--;
    return;
}
ora il mio dubbio è:
nel metodo Run è giusto creare un array di thread e attivarli mano a mano che ricevo connessioni
o sarebbe meglio avere un solo thread e farlo detached?
se si come?
Attualmente quando chiudo il programma ho un errore e credo sia dovuto al fatto di avere dei thread in sospeso.