c++ - 我想重新运行一个线程

标签 c++ windows multithreading winapi c++98

我正在用 C++ 实现 Java 风格的线程。为了做到这一点,我有一个 Thread::Start 函数,但我的问题是,当我使用它时,由于某种原因,它仅在第一次工作正常,一旦线程实例调用开始它完成但我无法再次调用开始并且都不调用其他线程的启动函数。

这是我的线程构造函数:

Thread::Thread()
{
    m_handle = (HANDLE)_beginthreadex(0, 0, &call, this, CREATE_SUSPENDED, 0);
}

线程析构函数:

Thread::~Thread()
{
    if (m_handle) CloseHandle(m_handle);
}

调用函数,它用作 Run 函数的包装器:

unsigned int __stdcall Thread::call(void* _this)
{
    ((Thread*)_this)->Run();
    return 0;
}

这是我的开始功能:

void Thread::Start()
{
    if (m_handle) ResumeThread(m_handle);
}

有问题的代码如下:

文员类:

struct Clerk : public Thread
{
    Clerk()
    {
        IsOnService = false;
    }
    void Run()
    {
        std::cout << this->GetId() << " receive new customer " << '\n';
        Sleep(2000);
        std::cout << this->GetId() << " has finished" << '\n';
        IsOnService = false;
    }

    bool IsOnService;
};

服务类:

struct Service
{
    Clerk*      clerk;
    Customer*   customer;
    Service(Clerk* c, Customer* cu)
    {
        clerk = c;
        customer = cu;
        clerk->Start();
    }
    ~Service()
    {
        delete customer;
    }
};

主要功能:

int main()
{
    int nClerks = 5;
    Clerk* clerks[] = { 
        new Clerk(), new Clerk(), new Clerk(), new Clerk(), new Clerk()
    };
    Queue<Customer*> awaitingCustomers;
    while (1) 
    {
        if (GetAsyncKeyState(0x43) & 0x7FFF) 
        {
            Customer* newCustomer = new Customer();
            awaitingCustomers.Push(newCustomer);
            while (!awaitingCustomers.IsEmpty())
            {
                for (int i = 0; i < nClerks; ++i)
                {
                    if (!clerks[i]->IsOnService)
                    {
                        Service* newService = new Service(clerks[i], awaitingCustomers.Pop());
                        delete newService;
                        break;
                    }
                }
            }
        }
    }
    for (int i = 0; i < nClerks; ++i) delete clerks[i];
    return 0;
}

当我运行上面的代码时,它只调用一次 Start 函数,而不是每次都调用它,因为我按下了“c”键。 我需要一个 c++98 解决方案,谢谢。

最佳答案

好吧,坏消息是您无法重新启动线程。即一旦线程退出,它就永远消失了,无法重新启动。

好消息是,无论如何,您可以做一些事情来有效地实现您想要的行为:

1) 调用WaitForSingleObject(m_handle, INFINITE);CloseHandle(m_handle);清理旧的/退出的线程,然后以与启动原始线程相同的方式启动新线程(即通过调用 _beginthreadex()ResumeThread() 等等)。这个逻辑都可以封装在你的Thread里面类,以便就任何调用代码而言,Thread 似乎已“重新启动”(尽管使用不同的线程 ID,如果这很重要的话)。

或者,或者(如果您不想每次都启动一个新线程的开销):

2) 从一开始就不要让你的线程退出。也就是说,让您的 thready-entry 函数执行如下操作(伪代码):

unsigned int __stdcall Thread::call(void* _this)
{
   while(timeToQuit == false)
   {
      // Do the normal Thread thing
      ((Thread*)_this)->Run();

      EnterCriticalSection(...);
      // we'll block here until the main thread wakes us up 
      SleepConditionVariableCS(...);
      LeaveCriticalSection(...);
   }
   return 0;
}

然后,每当您的主线程想要“重启”内部线程时,它就会调用 WakeConditionVariable在 Thread 对象的条件变量上将内部线程从其运行后 sleep 中唤醒,然后内部线程将调用 Run()再次。 (如果你想退出内部线程,除了先将 timeToQuit 设置为 true 之外,你会做同样的事情——而不是 timeToQuit 应该是 std::atomic<bool> 或类似的,以便线程安全)

关于c++ - 我想重新运行一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58151344/

相关文章:

c++ - 尝试访问文件以存储数据时,为什么C++ cmd屏幕挂起?

c++ - 抑制 system() 输出

c++ - 默认情况下,Windows 内存映射文件内容是否始终清零?

java - 网络服务器 : use Service instead of Thread

c++ - C++ 中的错误共享

java - 如何等待一个长进程的结束(在另一个线程上)?

c++ - 从用类方法编写的 lambda 函数访问类字段

c++ - 动态添加QWebEngineView到布局

c++ - 提供正确的 move 语义

C - 运行可执行文件并检索输出