我想重新运行一个线程

时间:2019-09-29 00:47:20

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

我正在用C ++实现Java样式线程。为了做到这一点,我有一个Thread :: Start函数,但是我的问题是,当我使用它时,由于某种原因,一旦线程实例调用开始运行它就完成了,但是它只能在第一次正常运行,但是我不能再次调用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 个答案:

答案 0 :(得分:1)

好吧,坏消息是您无法重新启动线程。即,线程退出后,它将永远消失并且无法重新启动。

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

1)调用WaitForSingleObject(m_handle, INFINITE);CloseHandle(m_handle);清理旧的/退出的线程,然后以与启动原始线程相同的方式启动新线程(即,调用_beginthreadex()和{ {1}},依此类推。此逻辑都可以封装在ResumeThread()类中,以便就任何调用代码而言,该线程似乎都在“重新启动”(如果有关系,则使用不同的线程ID)。

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

2)切勿首先退出线程。也就是说,让您的线程入口函数执行以下操作(伪代码):

Thread

然后,只要您的主线程想要“重新启动”内部线程,它将在Thread对象的条件变量上调用WakeConditionVariable,以将内部线程从运行后睡眠中唤醒,然后将内部线程唤醒会再次调用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; } 。 (并且,如果要退出内部线程,除了将Run()设置为true之外,您将做同样的事情-并非timeToQuit应该是timeToQuit或类似的名称,以便是线程安全的)