在cpp中从父线程暂停和恢复线程
Pause and resume thread from parent thread in cpp
我正在使用cpp线程库。我有一个父线程T1,它有一个子线程T2。T2只会循环一些项,做一些处理。我需要从T1使用函数调用暂停和恢复T2。T1和T2属于同一类。我需要它在特定事件达到T1时停止处理数据;请不要推荐任何其他线程实现库。
C::t2_func{
for(int i=0;i<data.size();i++)
process_data(data[i]);
}
C::spawn(){
t2 = std::make_unique<std::thread>(std::bind(&C::t2_func, this));
}
C::pause(){
//pause t2
}
C::resume(){
//resume t2
}
虽然不可能完全在线程外部暂停STL线程(某些具有更广泛线程管理功能的平台特定线程可能支持它),但是可以在线程的配合下暂停线程。请注意,这意味着暂停不会在线程执行期间的任意点发生,而只会在线程函数支持暂停的特定点发生。
暂停线程的核心非常简单:一个指示是运行还是暂停的标志。访问共享的线程数据,比如标志,必须是同步的;这是第二个方面,它必然使实现更加复杂,尽管不是非常复杂。
同步是通过锁(如lock_guard
和unique_lock
)在互斥锁上实现的;互斥锁确保代码的关键部分是互斥的(即不会被另一个中断),锁负责管理锁和解锁互斥锁。
另外,使用一个条件变量来表示线程应该运行:暂停线程等待,直到标志表示"运行",而恢复函数通知标志为"运行"。由于条件变量访问共享数据,所以它也使用互斥锁。std::condition_variable
支持两种等待方式:一种只是等待通知,但可能会遭受虚假唤醒,另一种需要一个可调用的谓词,并将等待通知和谓词返回true(允许虚假唤醒被忽略)。一般来说,后者是你想要的。
假设线程函数有空返回值,一个示例实现可以是:
// shared data, threading primitives
bool pause = false;
std::condition_variable cv;
std::mutex m;
// T2's main thread function
void C::t2_func() {
for(int i = 0; i < data.size(); i++){
// wait until unpause is signaled
nap();
// do some work
process_data(data[i]);
}
}
void C::spawn() {
t2 = std::make_unique<std::thread>(std::bind(&C::t2_func, this));
}
// thread management
void C::nap() {
// must use a `unique_lock` with a `condition_variable`, not a `lock_guard`
std::unique_lock<decltype(m)> lk(m);
cv.wait(lk, []{ return ! pause; });
}
void C::pause() {
//pause
std::lock_guard<decltype(m)> lk(m);
pause = true;
}
void C::resume() {
std::lock_guard<decltype(m)> lk(m);
pause = false;
cv.notify_one();
//resume t2
}
不能在外部暂停线程。但是线程可以暂停自己。考虑使用std::condition_variable和布尔标志is_paused
。然后在你的工作线程中,每次迭代你锁定一个互斥锁,检查线程是否应该暂停,如果应该,等待条件变量直到is_paused
重置为false。在主线程中锁定互斥锁,更改is_paused
并通知条件变量。
许多人在论坛上询问是否可以暂停、恢复或取消一个线程,不幸的是,目前我们不能。但如果有迫切需要,我有时会这样做。让你的函数增量(细粒度),这样它就可以在一个循环中连续执行,你可以像下面的一个简单的例子所示:
void main()
{
enum tribool { False,True,Undetermine};
bool running = true;
bool pause = false;
std::function<tribool(int)> func = [=](long n)
{
long i;
if (n < 2) return False;
else
if (n == 2) return True;
for (i = 2; i < n; i++)
{
while (pause)
{
if (!pause) break;
if (!running) return Undetermine;
}
if (n%i == 0) return False;
}
return True;
};
std::future<tribool> fu = std::async(func,11);
pause = true; //testing pause
pause = false;
auto result = fu.get();
if (result == True) std::cout << " Prime";
else
if (result == False) std::cout << " Not Prime";
else
std::cout << " Interrupted by user";
return ;
}
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- Lua/Luajit:暂停当前 Lua 线程
- 暂停和恢复多线程环境中另一个线程的线程C++技术建议
- 无法将线程与第三方库一起暂停
- 暂停和恢复线程的最佳解决方案是什么?
- POSIX:我如何暂停线程
- 超时时暂停线程
- mciSendString 不会暂停从线程播放的声音
- 在不使用自旋锁的情况下暂停空队列上的线程
- 频繁暂停和重启线程的最佳方法是什么?
- 如何暂停线程
- Std::async阻塞/暂停父线程
- 如何在Qt中取消线程暂停
- 在cpp中从父线程暂停和恢复线程