我想重新运行线程

问题描述 投票:0回答:1

我正在用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);
}

调用函数,用作运行函数的包装:

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解决方案。

c++ windows multithreading winapi c++98
1个回答
1
投票

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

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

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

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

2)永远不要让线程退出。也就是说,让您的线程入口函数执行以下操作(伪代码):

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;
}

然后,只要您的主线程想要“重新启动”内部线程,它将在Thread对象的条件变量上调用WakeConditionVariable,以将内部线程从运行后睡眠中唤醒,然后内部线程将调用[ C0]。 (并且,如果要退出内部线程,除了将Run()设置为true以外,您将执行相同的操作-并不是timeToQuit应该是timeToQuit或类似名称,才能保证线程安全)) >

© www.soinside.com 2019 - 2024. All rights reserved.