带有线程的C ++移动类

时间:2016-07-10 12:24:35

标签: c++ multithreading class c++11

我正在写服务器将处理客户端连接,但我有问题移动类与线程内部向量,我知道如果我只有线程我可以将其移动到矢量与std::move(),但在这里我有类中的线程,我遇到了很多错误,因为线程是不可移动的对象。

Core.cpp:

#define OS_LINUX

#include <iostream>
#include <vector>
#include <string>
#include <thread>

#include <csignal>
#include <cstdlib>

#include <TCPServer/TCPServer.h>
#include <TCPServer/TCPServerConnection.h>
#include <ProcessManip/ProcessManip.h>
#include <Log/Log.h>

#include "ConnectionHandler.h"

//Global
bool TERMNINATE = false;//If true loops must end
const int PORT = 8822;

//Proto
void terminate(int sig);
void receive_message(ConnectionHandler *handler,string message);

using namespace std;

int main(int argc,char *argv[])
{
  //Add Terminate handler
  signal(SIGINT,terminate);

  //Load configuration
  Log::logDebug("Starting ...");

  //Init
  vector<ConnectionHandler> connections;

  //Init modules

  //Main
  Log::logDebug("Running");
  TCPServer server;

  if(!server._bind(PORT))
    return 1;

  if(!server._listen())
    return 2;

  ProcessManip::cleanProcess(); /*  Clean dead processes */

  server.setBlocking(false);/* accept returns invalid socket if no connection */
  Log::logDebug("Listening ...");
  while(!TERMNINATE)
  {
    TCPServerConnection conn = server._accept();
    if(!conn.isValid())
      continue;

    Log::logDebug((string)"Got connection from: "+conn.getAddress());/* Print IP address of client */

    ConnectionHandler ch(&TERMNINATE,std::move(conn));
    ch.setCallback(receive_message);
    ch.start();
    connections.push_back(std::move(ch)); //here is problem

    /*connections.push_back(ConnectionHandler(&TERMNINATE,conn)); /* Add it to vector */
    /*connections.back().setCallback(receive_message);
    connections.back().start();*/
    Log::logDebug("Connection added to vector");


  }
  server.setBlocking(true);

  //Dispose
  Log::logDebug("Stopping ...");
  /*for(auto it = connections.begin();it!=connections.end();)
  {
      Log::logDebug((string)"Closed connection with: "+(*it).getConnection().getAddress());/* Print IP address of client */
      //(*it).close(); /* Close connetion */
    //  it = connections.erase(it); /* Delete ConnectionHandler from vector */
//  }

  server._close();

  Log::logDebug("Closed");
  return 0;
}

void terminate(int sig)
{
  //Change global value to true
  TERMNINATE = true;
}

void receive_message(ConnectionHandler *handler,string message)
{
  Log::logDebug((string)"Message ("+handler->getConnection().getAddress()+") : "+message);
}

ConnectionHandler.h

#ifndef EXT_CONNECTIONHANDLER
#define EXT_CONNECTIONHANDLER

#include <TCPServer/TCPServerConnection.h>
#include <thread>
#include <string>
#include <iostream>
#include <functional>

using namespace std;

class ConnectionHandler
{
public:
    ConnectionHandler(bool *pMainTerminate,TCPServerConnection pConnection);
    ConnectionHandler(TCPServerConnection pConnection);
    ~ConnectionHandler();

    void start(); /* Start listening */
    void stop(); /* Stop listening */
    void close(); /* Stops listening + close connection */

    void setConnection(TCPServerConnection pConnection);
    TCPServerConnection getConnection();

    void setCallback(function<void(ConnectionHandler*,string)> pFunction);


private:
    bool *mainTerminate = NULL;
    bool handler_terminate = false;
    short status = 0;
    TCPServerConnection connection;

    bool needTerminate();
    void run();
    void waitForEnd();

    function<void(ConnectionHandler*,string)> callback = NULL;

    std::thread m_thread;

};



#endif

ConnectionHandler.cpp

#include "ConnectionHandler.h"
ConnectionHandler::ConnectionHandler(bool *pMainTerminate,TCPServerConnection pConnection)
{
  this->mainTerminate = pMainTerminate;
  this->connection = pConnection;
}
ConnectionHandler::ConnectionHandler(TCPServerConnection pConnection)
{
  this->mainTerminate = NULL;
  this->connection = pConnection;
}
ConnectionHandler::~ConnectionHandler()
{
  this->close();
}
void ConnectionHandler::start()
{
  m_thread = std::thread(&ConnectionHandler::run, this);
  this->status = 1;
}

void ConnectionHandler::waitForEnd()
{
  if(this->m_thread.joinable())
    this->m_thread.join();
}

bool ConnectionHandler::needTerminate()
{
  if(mainTerminate!=NULL)
    return this->handler_terminate||*(this->mainTerminate);
  else
    return this->handler_terminate;
}

void ConnectionHandler::run()
{
  string message = "";
  string tmp = "";
  this->connection.setBlocking(false); // So we can terminate any time
  while(!this->needTerminate())
  {
    message = this->connection._receive();
    if(message!="")
    {
      do
      {
        tmp = this->connection._receive();
        message+=tmp;
      }while(tmp!=""); /* If we get longer message than we can grab at one time */
      this->connection._send(message); /* TODO Remove */

      if(this->callback!=NULL)
        this->callback(this,message);


      message = "";
    }
  }
  this->connection.setBlocking(true);
}

void ConnectionHandler::stop()
{
  this->handler_terminate = true; /* Signals thread to stop */
  this->waitForEnd();
  this->status = 2;
}

void ConnectionHandler::close()
{
  this->stop();
  this->connection._close(); /* Close connection */
  this->status = 3;
}

TCPServerConnection ConnectionHandler::getConnection()
{
  return this->connection;
}

void ConnectionHandler::setConnection(TCPServerConnection pConnection)
{
  this->connection = pConnection;
}
void ConnectionHandler::setCallback(function<void(ConnectionHandler*,string)> pFunction)
{
  this->callback = pFunction;
}

1 个答案:

答案 0 :(得分:3)

由于此课程violates the Rule Of Three,即使std::thread问题得到解决,也可能出现其他问题;最有可能采取神秘的运行时错误的形式。

std::thread的编译问题不是问题,它只是真正问题的症状:不应移动或复制此类。这个类应该只是new - 构造,然后填入std::shared_ptr(或合理的传真)并保持在那里直到它被破坏。只应传递std::shared_ptr,填入矢量等等......