- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用 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/
使用登录后,我想吐出用户名。 但是,当我尝试单击登录按钮时, 它给了我力量。 我看着logcat,但是什么也没显示。 这种编码是在说。 它将根据我在登录屏幕中输入的名称来烘烤用户名。 不会有任何密码。
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎是题外话,因为它缺乏足够的信息来诊断问题。 更详细地描述您的问题或include a min
我是一名优秀的程序员,十分优秀!