如何在c++中阻止函数从外部运行
How to stop a function from running from outside in c++
我想运行一个函数,如果函数在n毫秒后没有完成,则停止该函数并启动另一个函数。像这样的代码:
void run()
{
//do something that doesn't have while(1)
}
void main()
{
run();
if(runFunctionDidntFinishInSeconds(10)
{
endPrintFunction();
backupPlan();
}
return 0;
}
我搜索了一下,发现boost::timed_join函数。下面是我的代码:
void run()
{
int a;
for (int i = 0; i < 2000; i++)
cout << i << endl;
}
int main()
{
boost::thread t = new boost::thread(&run);
if (t.timed_join(boost::posix_time::microseconds(10000))){
cout << "done" << endl;
}
else{
cout << endl << "not done" << endl;
}
system("pause");
return 0;
}
但是它不能阻止线程't'的运行。我去终止线程,但这不是一个好的选择。我想让a函数在我指定的时间完成。系统每16毫秒得到一次输入,我想对它做一个处理,如果处理时间超过13毫秒,就离开它,去做一个备份计划。我想把它从写处理方法的人那里抽象出来。所以在它上面放一个while循环会带来延迟。我该怎么办?至少我认为我需要的是能够重置处理线程来做它需要再次做的事情!
我想你是在找类似std::future的东西。
http://en.cppreference.com/w/cpp/thread/future/wait_for可以在另一个线程中启动函数,然后等待函数返回或超时。
例如:
std::future< void > future = std::async( std::launch::async, print );
auto status = future.wait_for( std::chrono::seconds( 10 ) );
if ( status == std::future_status::deferred )
{
std::cout << "deferredn";
}
else if ( status == std::future_status::timeout )
{
std::cout << "timeoutn";
}
else if ( status == std::future_status::ready )
{
std::cout << "ready!n";
}
但是,这不会导致分离的线程结束。为此,有必要在启动时包含一个标志,以便分离的线程可以自己清理并保存退出。
void run(const std::atomic_bool& cancelled)
{
int a;
for (int i = 0; i < 2000; i++)
{
cout << i << endl;
if (cancelled)
return;
}
}
std::atomic_bool cancellation_token = false;
std::future< void > future = std::async( std::launch::async,
run,
std::ref(cancellation_token) );
auto status = future.wait_for( std::chrono::seconds( 10 ) );
if ( status == std::future_status::deferred )
{
std::cout << "deferredn";
}
else if ( status == std::future_status::timeout )
{
std::cout << "timeoutn";
cancellation_token = true;
}
else if ( status == std::future_status::ready )
{
std::cout << "ready!n";
}
我想把它从编写处理方法的人那里抽象出来。
标准c++没有办法从函数调用图的外部强制中断函数的控制流(它调用的函数可以抛出,但是有人不能为他们抛出)。
特定于os的线程系统有终止线程的方法。然而,这可能使程序处于未定义状态,因为没有调用任何堆栈变量的析构函数。由于你在杀死它的过程中不知道它在哪里,所以你无法有效地清理它。即使是C程序也不能保证任意函数可以被终止;它必须是一个不动态分配内存或其他必须清理的资源。
您可以通过非常仔细地编写函数来弥补这一点。但是这要求编写这个函数的人非常仔细地编写。因此,不存在抽象,因为编写函数的人必须知道规则是什么,并且必须遵循这些规则。
所以唯一有效的解决方案需要合作。该函数必须以这样一种方式编写,即可以通过那些依赖于操作系统的特性安全地停止它,或者必须定期检查一些值并停止本身。
这里有两个又3/4个方法。
第一个要求您想要停止的代码合作。它要么在运行时轮询某个变量,要么定期调用可能抛出异常以停止执行的函数。boost
可中断线程遵循第二种模式。
第二种方法要求启动一个新进程,将数据编组到函数,并使用IPC获取回信息。如果函数没有及时返回,则终止子进程。
第三个"一半"包括用不同的语言重写代码,或者使用c++作为脚本语言。您在解释器中运行代码,解释器为您执行第一种或第二种解决方案。
现在,一个实际的替代方案(1/4解决方案)是确保函数是纯功能性的,在一个单独的线程中运行它,并带有半可靠的中止消息(如第一个),并且如果花费太长时间就丢弃它的返回值。这不是您想要的,但要简单得多。
有一种方法可以将原子用作信号量,但这会产生完全的内存屏障,从而降低性能,因为每次迭代都有load
:
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
std::atomic<bool> printFinished { false };
std::atomic<bool> shouldPrintRun { true };
void print()
{
while (shouldPrintRun.load() /* && your normal stop condition*/)
{
//work..
}
printFinished.store(true);
}
int main()
{
std::thread t(print);
std::this_thread::sleep_for(std::chrono::seconds(10));
if (!printFinished.load())
{
shouldPrintRun.store(false);
t.join();
std::cout << "help!";
}
return 0;
}
如果你不想让在另一个线程上运行的函数检查它是否需要停止,那么终止该线程是only选项。
一个可能的解决方案是,你必须把这个冗长的函数变成小的&短增量函数,它将在每次调用时继续执行任务。下面可以在线程中运行的代码将执行与时间切片器类似的工作,并且可以随意终止。
void Process()
{
bool flag = true;
while (running)
{
std::chrono::high_resolution_clock::time_point time1 = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds span(16);
while ( (std::chrono::high_resolution_clock::now() - time1 ) < span)
{
flag ? incremental_function1() : incremental_function2();
if (!running) return;
}
flag = (!flag);
}
}
- 如何在 C/C++ 中从外部库调用函数
- 从外部文件C++调用函数
- 如何将值从外部传递到结构函数
- 我可以有一个从外部不可见但未在标头中定义的静态友元函数吗?
- C ++ tiny-js 从外部文件执行 JavaScript 函数
- 从外部函数访问外部结构属性
- 使用从外部参数包中获取的参数类型声明函数
- 为什么局部类定义可以从同一函数访问外部静态变量
- 从外部调用静态C函数
- 调用外部函数(从一个exe到另一个exe)
- 如何从外部文件调用C++函数
- C++:如何从外部调用父类函数
- 从外部静态库访问函数
- 将以null结尾的字符串列表从外部函数返回到.NET中
- 从外部使用"class::func()"调用非静态函数或构造函数
- 从函数返回 const 对象是否会阻止从外部移动构造
- 从外部函数/类设置动态数组的新大小
- 从外部调用封装类成员函数时不加载SFML纹理
- 如何在c++中阻止函数从外部运行
- 我如何使用函数从外部库