Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;移动带有线程的类_C++_Multithreading_Class_C++11 - Fatal编程技术网

C++ C++;移动带有线程的类

C++ C++;移动带有线程的类,c++,multithreading,class,c++11,C++,Multithreading,Class,C++11,我正在编写服务器,它将处理客户端连接,但我在将类和线程一起移动到向量时遇到问题,我知道如果我只有线程,我可以使用std::move(),将其移动到向量,但在这里,我有一个类中的线程,我得到了很多错误,因为线程是不可移动的对象 Core.cpp: #定义OS_LINUX #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括“ConnectionHandler.h” //全球的 bool-TERMNINATE=假//如果为true,则循环必须结束 const int

我正在编写服务器,它将处理客户端连接,但我在将类和线程一起移动到向量时遇到问题,我知道如果我只有线程,我可以使用
std::move()
,将其移动到向量,但在这里,我有一个类中的线程,我得到了很多错误,因为线程是不可移动的对象

Core.cpp:

#定义OS_LINUX
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“ConnectionHandler.h”
//全球的
bool-TERMNINATE=假//如果为true,则循环必须结束
const int PORT=8822;
//原型
无效终止(int sig);
无效接收消息(ConnectionHandler*handler,字符串消息);
使用名称空间std;
int main(int argc,char*argv[])
{
//添加终止处理程序
信号(SIGINT,终止);
//负载配置
Log::logDebug(“启动…”);
//初始化
向量连接;
//初始化模块
//主要
Log::logDebug(“正在运行”);
TCPServer服务器;
如果(!服务器。\u绑定(端口))
返回1;
如果(!server.\u listen())
返回2;
ProcessManip::cleanProcess();/*清除死进程*/
server.setBlocking(false);/*accept在没有连接时返回无效套接字*/
Log::logDebug(“侦听…”);
而(!TERMNINATE)
{
TCPServerConnection conn=server._accept();
如果(!conn.isValid())
继续;
Log::logDebug((字符串)“从以下位置获得连接:“+conn.getAddress());/*打印客户端的IP地址*/
连接处理器ch(&TERMNINATE,std::move(conn));
ch.setCallback(接收消息);
ch.start();
连接。推回(std::move(ch));//问题出在这里
/*connections.push_back(ConnectionHandler(&TERMNINATE,conn));/*将其添加到向量*/
/*connections.back().setCallback(接收消息);
connections.back().start()*/
logDebug(“连接添加到向量”);
}
server.setBlocking(true);
//处置
Log::logDebug(“停止…”);
/*for(auto it=connections.begin();it!=connections.end();)
{
Log::logDebug((字符串)“已关闭连接:”+(*it).getConnection().getAddress());/*打印客户端的IP地址*/
//(*it).close();/*关闭连接*/
//it=连接。擦除(it);/*从向量中删除ConnectionHandler*/
//  }
服务器。_close();
Log::logDebug(“关闭”);
返回0;
}
无效终止(int sig)
{
//将全局值更改为true
TERMNINATE=真;
}
无效接收消息(ConnectionHandler*处理程序,字符串消息)
{
Log::logDebug((字符串)“消息(“+handler->getConnection().getAddress()+”:“+Message”);
}
ConnectionHandler.h

\ifndef EXT\u CONNECTIONHANDLER
#定义EXT_CONNECTIONHANDLER
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
类连接处理程序
{
公众:
ConnectionHandler(bool*pmanimitate,TCPServerConnection-pConnection);
ConnectionHandler(TCPServerConnectionPConnection);
~ConnectionHandler();
void start();/*开始侦听*/
void stop();/*停止侦听*/
void close();/*停止侦听并关闭连接*/
void setConnection(TCPServerConnection pcconnection);
TCPServerConnection getConnection();
void setCallback(函数pffunction);
私人:
bool*mainteminate=NULL;
bool handler_terminate=false;
短状态=0;
tcpserver连接;
bool needTerminate();
无效运行();
void waitForEnd();
函数回调=NULL;
标准:螺纹m_螺纹;
};
#恩迪夫
ConnectionHandler.cpp

#包括“ConnectionHandler.h”
ConnectionHandler::ConnectionHandler(bool*pmamintenate,TCPServerConnection-pcConnection)
{
此->mainTerminate=pMainTerminate;
此->连接=P连接;
}
ConnectionHandler::ConnectionHandler(TCPServerConnectionPConnection)
{
此->mainteminate=NULL;
此->连接=P连接;
}
ConnectionHandler::~ConnectionHandler()
{
此->关闭();
}
void ConnectionHandler::start()
{
m_thread=std::thread(&ConnectionHandler::run,this);
该->状态=1;
}
void ConnectionHandler::waitForEnd()
{
如果(此->m_thread.joinable())
此->m_thread.join();
}
bool ConnectionHandler::needTerminate()
{
如果(mainteminate!=NULL)
返回此->处理程序|终止|*(此->主终止);
其他的
返回此->处理程序\u终止;
}
void ConnectionHandler::run()
{
字符串消息=”;
字符串tmp=“”;
this->connection.setBlocking(false);//因此我们可以随时终止
而(!this->needTerminate())
{
message=此->连接。_receive();
如果(消息!=“”)
{
做
{
tmp=此->连接。u receive();
消息+=tmp;
}while(tmp!=“”);/*如果我们收到的消息比我们一次能抓到的要长*/
此->连接。_发送(消息);/*要删除吗*/
如果(此->回调!=NULL)
此->回调(此,消息);
message=“”;
}
}
此->连接.setBlocking(true);
}
void ConnectionHandler::stop()
{
此->处理程序\u terminate=true;/*指示线程停止*/
这->waitForEnd();
该->状态=2;
}
void ConnectionHandler::close()
{
此->停止();
此->连接。_close();/*关闭连接*/
该->状态=3;
}
TCPServerConnection ConnectionHandler::getConnection()
{
返回此->连接;
}
void ConnectionHandler::setConnection(TCPServerConnection-pcconnection)
{
此->连接=P连接;
}
void ConnectionHandler::setCallback(函数pFunction)
{
此->回调=p函数;
}
因为这个类,即使
std::thread
问题得到解决,也可能出现其他问题;最有可能的形式是神秘的运行时bug

std::thread
的编译问题不是问题所在,它只是真正问题的一个症状:不应该移动或复制此类。这个类只应该是新的,然后塞进一个共享的文件(或者一个合理的传真文件),直到它被销毁。只有
std::shared\u ptr
应该
#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);
}
#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
#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;
}