c++ - 内部类和初始化

标签 c++ boost-thread

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

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 的外部类的 workers 数组。

我想要的是工作线程 vector 。每个工作线程都有自己的状态,但可以访问一些其他共享数据(未显示)。另外,如何创建线程。它们应该在类对象首次创建时创建,还是在 thread_group 外部创建。

另外,我该如何干净安全地关闭线程?

编辑:

看来我可以这样初始化Worker:

Server::Server(int thread_count) 
  : _workers(thread_count), Worker(*this)), _thread_count(thread_count) { }

我目前正在 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();
}

有人发现这有什么问题吗? 安全关机怎么样?

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

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

最佳答案

我用纯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;
}

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

关于c++ - 内部类和初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4132454/

相关文章:

c++ - 如何使用 boost atomic 来消除竞争条件?

c++ - Boost::thread 在简单循环期间崩溃

c++ - 如何避免与 `asio::ip::tcp::iostream` 的数据竞争?

c++ - tr1::hash 用于 boost::thread::id?

C++, Linux : error: conversion from ‘boost::unique_future<void>’ to non-scalar type ‘boost::shared_future<void>’ requested. 如何绕过它?

c++ - 如何在 C++ 中将一个 .exe 链接到另一个 .exe

c++ - 有效地在 C++ 类之间传输数据

c++ - 为什么这段带有 std::chrono::system_clock 的代码不工作?

c++ - 修改 .ui 文件需要一个 `make clean`