Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.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++_Boost Thread - Fatal编程技术网

C++ 内部类和初始化

C++ 内部类和初始化,c++,boost-thread,C++,Boost Thread,我有一个这样定义的类:这个类并不完整,可能无法编译 class Server { public: Server(); ~Server(); class Worker { public: Worker(Server& server) : _server(server) { } ~Worker() { } void Run() { } void Stop() { } private: Server& _ser

我有一个这样定义的类:这个类并不完整,可能无法编译

class Server
{
public:
  Server();
  ~Server();

  class Worker
  {
  public: 
    Worker(Server& server) : _server(server) { }
    ~Worker() { }

    void Run() { }
    void Stop() { }

  private:  
    Server& _server;
  }


  void Run()
  {
    while(true) {
       // do work
    }
   }

  void Stop()
  {
     // How do I stop the thread?
  }

private:
  std::vector<Worker> _workers;
};
我目前正在Server::Run中创建线程

boost::thread_group _threads; // a Server member variable 

Server::Run(){
   for (int i = 0; i < _thread_count; i++)
     _threads.create_thread(boost::bind(&Server::Worker::Run, _workers(i)));

   // main thread.
   while(1) {  
       // Do stuff
   }

   _threads.join_all();
}
boost::thread\u group\u threads;//服务器成员变量
服务器::运行(){
对于(int i=0;i<\u线程数;i++)
_创建线程(boost::bind(&Server::Worker::Run,_workers(i));
//主线程。
而第(1)款{
//做事
}
_线程。连接所有线程();
}
有人认为这有什么问题吗? 安全关机怎么样

编辑: 我发现的一个问题是Worker对象似乎没有被构造! 哎呀。是的,我需要工人类上的复制构造函数


但奇怪的是,创建线程会导致Worker的复制构造函数被多次调用。

您有没有看过boost asio?看起来它可能非常适合你正在尝试做的事情。此外,您可以从多个线程调用boost asio的io_服务的run(类似于您的run方法),也就是说,您可以在多个线程中处理io。同样值得关注的是基于asio的线程池


看看asio的例子。也许它们提供了另一种处理您试图做的事情的方法。特别是,看看如何完成干净的关机。

我已经用纯WINAPI完成了,看:

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <vector>

using namespace std;

class Server
{

public:

    class Worker
    {
        int     m_id;
        DWORD   m_threadId;
        HANDLE  m_threadHandle;
        bool    m_active;

        friend Server;

    public:

        Worker (int id)
        {
            m_id = id;
            m_threadId = 0;
            m_threadHandle = 0;
            m_active = true;
        }

        static DWORD WINAPI Run (LPVOID lpParam)
        {
            Worker* p = (Worker*) lpParam;      // it's needed because of the static modifier

            while (p->m_active)
            {
                printf ("I'm a thread #%i\n",  p->m_id);
                Sleep (1000);
            }

            return 0;
        }

        void Stop ()
        {
            m_active = false;
        }
    };

    Server ()
    {
        m_workers = new vector <Worker*> ();
        m_count = 0;
    }

    ~Server ()
    {
        delete m_workers;
    }

    void Run ()
    {
        puts ("Server is run");
    }

    void Stop ()
    {
        while (m_count > 0)
            RemoveWorker ();

        puts ("Server has been stopped");
    }

    void AddWorker ()
    {
        HANDLE  h;
        DWORD   threadId;

        Worker* n = new Worker (m_count ++);
        m_workers->push_back (n);

        h = CreateThread (NULL, 0, Worker::Run, (VOID*) n, CREATE_SUSPENDED, &threadId);
        n->m_threadHandle = h;
        n->m_threadId = threadId;
        ResumeThread (h);
    }

    void RemoveWorker ()
    {
        HANDLE  h;
        DWORD   threadId;

        if (m_count <= 0)
            return;

        Worker* n = m_workers->at (m_count - 1);
        m_workers->pop_back ();

        n->Stop ();
        TerminateThread (n->m_threadHandle, 0);

        m_count --;

        delete n;
    }

private:

    int                 m_count;
    vector <Worker*>*   m_workers;
};

int main (void)
{
    Server  a;
    int     com = 1;

    a.Run ();

    while (com)
    {
        if (kbhit ())
        {
            switch (getch ())
            {
            case 27:        // escape key code

                com = 0;
                break;

            case 'a':       // add worker

                a.AddWorker ();
                break;

            case 'r':       // remove worker

                a.RemoveWorker ();
                break;

            }
        }
    }

    a.Stop ();

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
类服务器
{
公众:
班主任
{
国际货币基金组织;
德沃德·穆特莱德;
手柄m_螺纹手柄;
布尔穆活跃;
好友服务器;
公众:
工作人员(内部id)
{
m_id=id;
m_threadId=0;
m_threadHandle=0;
m_active=真;
}
静态DWORD WINAPI运行(LPVOID lpParam)
{
Worker*p=(Worker*)lpParam;//由于使用了静态修饰符,所以需要它
当(p->m_激活时)
{
printf(“我是一个线程#%I\n”,p->m\u id);
睡眠(1000);
}
返回0;
}
无效停止()
{
m_active=false;
}
};
服务器()
{
m_workers=新向量();
m_计数=0;
}
~Server()
{
删除m_工人;
}
无效运行()
{
puts(“服务器正在运行”);
}
无效停止()
{
而(m_计数>0)
解雇工人();
puts(“服务器已停止”);
}
void AddWorker()
{
手柄h;
德沃德·特莱德;
工人*n=新工人(m_计数++);
m_工人->推回(n);
h=CreateThread(NULL,0,Worker::Run,(VOID*)n,CREATE\u SUSPENDED,&threadId);
n->m_threadHandle=h;
n->m_threadId=threadId;
(h);
}
void RemoveWorker()
{
手柄h;
德沃德·特莱德;
if(m_count at(m_count-1);
m_workers->pop_back();
n->Stop();
TerminateThread(n->m_threadHandle,0);
m_count--;
删除n;
}
私人:
国际货币单位计数;
向量*m_工作者;
};
内部主(空)
{
服务器a;
int com=1;
a、 运行();
while(com)
{
if(kbhit())
{
开关(getch())
{
案例27://转义键代码
com=0;
打破
案例“a”://添加工作程序
a、 AddWorker();
打破
案例'r'://删除工作进程
a、 解雇工人();
打破
}
}
}
a、 停止();
返回0;
}

这里没有同步代码,因为我没有足够的时间来做…但我希望它能帮助您=)

输入队列来自哪里?您要创建多少工人?我已删除输入队列。我认为这会把事情弄糊涂。我要创建的worker的数量是可变的,并且来自配置文件。您真的需要在另一个类中定义一个类吗?这只会让我读起来不那么容易。我会把你的问题留给更聪明的人。我只是想指出行'Worker(Server&Server):\u Server(&Server){}是错误的。应该是“Worker(Server&Server):\u Server(Server){}否,但是内部类需要访问外部类成员,因此如果它是外部类,那么我需要将其作为朋友。内部类只会被使用,但外部类会被使用。是的,它实际上在使用ASIO!例如,对于同步,可以使用关键部分
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <vector>

using namespace std;

class Server
{

public:

    class Worker
    {
        int     m_id;
        DWORD   m_threadId;
        HANDLE  m_threadHandle;
        bool    m_active;

        friend Server;

    public:

        Worker (int id)
        {
            m_id = id;
            m_threadId = 0;
            m_threadHandle = 0;
            m_active = true;
        }

        static DWORD WINAPI Run (LPVOID lpParam)
        {
            Worker* p = (Worker*) lpParam;      // it's needed because of the static modifier

            while (p->m_active)
            {
                printf ("I'm a thread #%i\n",  p->m_id);
                Sleep (1000);
            }

            return 0;
        }

        void Stop ()
        {
            m_active = false;
        }
    };

    Server ()
    {
        m_workers = new vector <Worker*> ();
        m_count = 0;
    }

    ~Server ()
    {
        delete m_workers;
    }

    void Run ()
    {
        puts ("Server is run");
    }

    void Stop ()
    {
        while (m_count > 0)
            RemoveWorker ();

        puts ("Server has been stopped");
    }

    void AddWorker ()
    {
        HANDLE  h;
        DWORD   threadId;

        Worker* n = new Worker (m_count ++);
        m_workers->push_back (n);

        h = CreateThread (NULL, 0, Worker::Run, (VOID*) n, CREATE_SUSPENDED, &threadId);
        n->m_threadHandle = h;
        n->m_threadId = threadId;
        ResumeThread (h);
    }

    void RemoveWorker ()
    {
        HANDLE  h;
        DWORD   threadId;

        if (m_count <= 0)
            return;

        Worker* n = m_workers->at (m_count - 1);
        m_workers->pop_back ();

        n->Stop ();
        TerminateThread (n->m_threadHandle, 0);

        m_count --;

        delete n;
    }

private:

    int                 m_count;
    vector <Worker*>*   m_workers;
};

int main (void)
{
    Server  a;
    int     com = 1;

    a.Run ();

    while (com)
    {
        if (kbhit ())
        {
            switch (getch ())
            {
            case 27:        // escape key code

                com = 0;
                break;

            case 'a':       // add worker

                a.AddWorker ();
                break;

            case 'r':       // remove worker

                a.RemoveWorker ();
                break;

            }
        }
    }

    a.Stop ();

    return 0;
}