需要在c++; 我正在编写一个C++程序,需要在一个周期的时间间隔内调用一个函数,比如说每10ms左右调用一个函数。我从来没有做过与C++中的时间或时钟有关的事情,这是一个简单又容易的问题,还是没有一个好的解决方案?

需要在c++; 我正在编写一个C++程序,需要在一个周期的时间间隔内调用一个函数,比如说每10ms左右调用一个函数。我从来没有做过与C++中的时间或时钟有关的事情,这是一个简单又容易的问题,还是没有一个好的解决方案?,c++,visual-c++,timer,C++,Visual C++,Timer,谢谢 您可以研究线程: 这里是一个用C实现的时间间隔控制函数,使用pthult.h,它应该是一个简单的C++端口。 一个简单的计时器可以实现如下: #include <iostream> #include <chrono> #include <thread> #include <functional> void timer_start(std::function<void(void)> func, unsigned int inter

谢谢

您可以研究线程:

这里是一个用C实现的时间间隔控制函数,使用pthult.h,它应该是一个简单的C++端口。


一个简单的计时器可以实现如下:

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>

void timer_start(std::function<void(void)> func, unsigned int interval)
{
    std::thread([func, interval]() {
        while (true)
        {
            func();
            std::this_thread::sleep_for(std::chrono::milliseconds(interval));
        }
    }).detach();
}


void do_something()
{
    std::cout << "I am doing something" << std::endl;
}

int main() {
    timer_start(do_something, 1000);

    while(true);
}
#包括
#包括
#包括
#包括
无效计时器\u启动(标准::函数func,无符号整数间隔)
{
线程([func,interval](){
while(true)
{
func();
std::this_线程::sleep_for(std::chrono::毫秒(间隔));
}
}).detach();
}
空做某事
{

std::cout这取决于您在每个间隔上要做什么-在屏幕/窗体的特定位置显示时间/计时器或其他东西。或者您可能需要将常规数据发送到连接的机器(通过插座或管道)。您真的需要10毫秒的精度吗

根据要求,特别是精度要求,您可能有专门的线程来做“某事”,然后等待并再次做同样的事情。或者,在Windows上,您可以使用
SetTimer
在每个间隔触发
WM_TIMER
事件(不需要线程)。您也可以使用可等待计时器、多媒体计时器等


最后,但非常重要的是-您需要平台和编译器兼容性吗?也就是说,您将使用哪个操作系统,或者您需要平台无关的操作系统?您需要什么编译器功能(C++11、C++14或C++11之前的版本)如果你用VisualC++编程,你可以在你想调用的周期函数中添加一个定时器元素(这里是我的形式是“代码>主窗体< /代码>,我的计时器<代码>主定时器< /C> >)。在事件中添加一个调用事件。设计器将在你的.h文件中添加这样的行:

this->MainTimer->Enabled = true;
this->MainTimer->Interval = 10;
this->MainTimer->Tick += gcnew System::EventHandler(this, &MainForm::MainTimer_Tick);
然后,在每个间隔(以毫秒为单位指定),应用程序将调用此函数

private: System::Void MainTimer_Tick(System::Object^  sender, System::EventArgs^  e) {
   /// Enter your periodic code there
}

为了完成这个问题,@user534498中的代码可以很容易地调整为具有周期性的勾号间隔。 只需在计时器线程循环开始时确定下一个开始时间点,并在执行该函数后
sleep\u直到该时间点

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>

void timer_start(std::function<void(void)> func, unsigned int interval)
{
  std::thread([func, interval]()
  { 
    while (true)
    { 
      auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
      func();
      std::this_thread::sleep_until(x);
    }
  }).detach();
}

void do_something()
{
  std::cout << "I am doing something" << std::endl;
}

int main()
{
  timer_start(do_something, 1000);
  while (true)
    ;
}
#包括
#包括
#包括
#包括
无效计时器\u启动(标准::函数func,无符号整数间隔)
{
线程([func,interval]()
{ 
while(true)
{ 
自动x=std::chrono::Standy_clock::now()+std::chrono::毫秒(间隔);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
空做某事
{

很抱歉,我没有发现比这更简单的设计

您可以创建一个同时拥有一个线程和一个
弱ptr
的类, 作为一个“持有者”,被调用者可以安全地看到它,因为被调用者 即使对象被破坏,也将仍然存在。您不需要悬空指针

template<typename T>
struct IntervalRepeater {
    using CallableCopyable = T;
private:
    weak_ptr<IntervalRepeater<CallableCopyable>> holder;
    std::thread theThread;

    IntervalRepeater(unsigned int interval,
            CallableCopyable callable): callable(callable), interval(interval) {}

    void thread() {
        weak_ptr<IntervalRepeater<CallableCopyable>> holder = this->holder;
        theThread = std::thread([holder](){
            // Try to strongify the pointer, to make it survive this loop iteration,
            //    and ensure that this pointer is valid, if not valid, end the loop.
            while (shared_ptr<IntervalRepeater<CallableCopyable>> ptr = holder.lock()) {
                auto x = chrono::steady_clock::now() + chrono::milliseconds(ptr->interval);
                ptr->callable();
                this_thread::sleep_until(x);
            }
        });
    }

public:
    const CallableCopyable callable;
    const unsigned int interval;

    static shared_ptr<IntervalRepeater<T>> createIntervalRepeater(unsigned int interval,
            CallableCopyable callable) {
        std::shared_ptr<IntervalRepeater<CallableCopyable>> ret =
                shared_ptr<IntervalRepeater<CallableCopyable>>(
                        new IntervalRepeater<CallableCopyable>(interval, callable));
        ret->holder = ret;
        ret->thread();

        return ret;
    }

    ~IntervalRepeater() {
        // Detach the thread before it is released.
        theThread.detach();
    }

};

void beginItWaitThenDestruct() {
    auto repeater = IntervalRepeater<function<void()>>::createIntervalRepeater(
            1000, [](){ cout << "A second\n"; });
    std::this_thread::sleep_for(std::chrono::milliseconds(3700));
}

int main() {
    beginItWaitThenDestruct();
    // Wait for another 2.5 seconds, to test whether there is still an effect of the object
    //   or no.
    std::this_thread::sleep_for(std::chrono::milliseconds(2500));
    return 0;
}
模板
结构间隔中继器{
使用CallableCopyable=T;
私人:
弱ptr支架;
std::线程线程;
IntervalRepeater(无符号整数间隔,
CallableCopyable callable):可调用(callable),interval(interval){}
无效线程(){
弱\u ptr holder=此->holder;
thread=std::thread([holder](){
//尝试加强指针,使其在循环迭代中生存,
//并确保该指针有效,如果无效,则结束循环。
while(shared_ptr ptr=holder.lock()){
自动x=chrono::Standy_clock::now()+chrono::毫秒(ptr->interval);
ptr->callable();
此线程::sleep_until(x);
}
});
}
公众:
常量可调用可复制可调用;
常量无符号整数间隔;
静态共享\u ptr createIntervalRepeater(无符号整数间隔,
可调用可复制可调用){
std::共享\u ptr ret=
共享ptr(
新的IntervalRepeater(interval,可调用));
ret->holder=ret;
ret->thread();
返回ret;
}
~IntervalRepeater(){
//松开螺纹之前,请将其拆下。
theThread.detach();
}
};
void beginItWaitThenDestruct(){
自动转发器=IntervalRepeater::createIntervalRepeater(

1000,[](){cout这是一篇相当古老的帖子,但我找到了一个非常简单的解决方案,我想 分享它:

解决办法是

#include "unistd.h"
并使用上述库中包含的函数

usleep(int) 
例如,这将每3000微秒调用一个函数

int main() {

    int sleep_time = 3000;
    while(true) { 

          usleep(sleep_time);

          call function;
    }

    return 0;
}

我也将其用于串行和并行代码,并且在这两种情况下都能工作!

我为自己制作了一个异步系统。它不应该与
std::async混为一谈。由于它是定制的,我可以完全控制时间线,因此我可以添加、编辑、删除、附加等任务。它主要在一个线程中运行,并保证上下文之间的安全xt交换机,但也支持多线程同步。试着创建您自己的异步系统,根据我的经验,我认为这是值得的。

有这种支持。@user534498不幸的是,您的解决方案不会按他要求的那样做。它将在调用之间以
间隔
延迟执行
func
。它不会执行
func>
一次间隔
。如果
func
可能需要一些可变的时间来运行,则启动时间也会有所不同。这是正确的方法,请注意
func()
必须在
睡眠结束之前完成,直到
睡眠结束!@florgeng,如果函数do\u something接受参数怎么办?@EdisonLo您可以使用std::bind将参数绑定到函数。例如:
do\u something 2(int i)
如果您想用i=25调用它,那么调用
timer\u start(std::bind)(do