struct taskinfo
{
long int id;
bool cancel;
std::function<void()> func;
std::chrono::system_clock::time_point time;
std::chrono::system_clock::duration interval;
taskinfo(){ }
bool operator<(const taskinfo& task) const {
return time > task.time;
}
public:
taskinfo(long int id, std::function<void()>&& f, const std::chrono::system_clock::time_point& t)
: id(id), func(f),
time(t)
{
cancel = false;
}
}
....
std::priority_queue<taskinfo, std::vector<taskinfo>> tasks;
void at(taskinfo** task){
std::function<void()> threadFunc = [task]() { std::thread((*task)->func).detach(); };
(*task)->func = threadFunc;
tasks.push(**task);
}
在main()..
std::vector<taskinfo*> requests;
for(int i=1; i <=5; i++ )
{
taskinfo* t = new taskinfo(i, [i]{ timeoutFunc(i); }, std::chrono::system_clock::now() + std::chrono::milliseconds(timeout));
tT.at(&t);
requests.push_back(t);
std::cout << "Request " << i << " Registered.... Time:" << std::chrono::system_clock::now().time_since_epoch().count() << std::endl;
}
我认为当我将该函数从队列中弹出来执行时,我在这里遗漏了一些东西,该函数可能为空,没有执行任何操作。
如果我将taskinfo复制到本地
void at(taskinfo** task){
taskinfo t = **task;
//Replace everything else with t function works fine But
//I need to modify the same reference
}
我如何在这里使用指针参考lambda?
我已经添加了我在这里尝试做的完整代码。
完整代码:
#include <functional>
#include <chrono>
#include <future>
#include <queue>
#include <thread>
#include <memory>
#include <sstream>
#include <assert.h>
#include <iostream>
#include <ctime>
#include <sys/time.h>
#include <unistd.h>
#include <limits.h>
#define TIMER_NO_TASK_SLEEP_TIME 100
struct taskinfo
{
long int id;
bool cancel;
std::function<void()> func;
std::chrono::system_clock::time_point time;
std::chrono::system_clock::duration interval;
taskinfo(){ }
bool operator<(const taskinfo& task) const {
return time > task.time;
}
public:
taskinfo(long int id, std::function<void()>&& f, const std::chrono::system_clock::time_point& t)
: id(id), func(f),
time(t)
{
cancel = false;
}
};
class TimerTask
{
private:
std::priority_queue<taskinfo, std::vector<taskinfo>> tasks;
std::unique_ptr<std::thread> thread;
bool keepRunning;
public:
TimerTask()
:keepRunning(true),
thread(new std::thread([this]() {
while(keepRunning)
{
auto now = std::chrono::system_clock::now();
while(!tasks.empty() && tasks.top().time <= now) {
if(!tasks.top().cancel)
{
tasks.top().func();
}
tasks.pop();
}
if(tasks.empty()) {
std::this_thread::sleep_for(std::chrono::milliseconds(TIMER_NO_TASK_SLEEP_TIME));
} else {
std::this_thread::sleep_for(tasks.top().time - std::chrono::system_clock::now());
}
}
})){ }
~TimerTask()
{
keepRunning = false;
thread->join();
}
//Execute a task when the timer times out
void at(taskinfo** task){
std::function<void()> threadFunc = [task]() { std::thread((*task)->func).detach(); };
(*task)->func = threadFunc;
tasks.push(**task);
}
//Cancel the particular task with a flag
void cancel(taskinfo** task){
(* task)->cancel = true;
}
};
//The return type of the task must be void
void timeoutFunc(int id)
{
std::cout << "Request " << id << " Timeout.... Executed Timeout Function Time:" << std::chrono::system_clock::now().time_since_epoch().count() << std::endl;
}
int main(int argc, char* argv[])
{
if(argc != 2)
{
std::cout << "\n Usage <Process> <Timeout>" << std::endl;
return 0;
}
int timeout = atoi(argv[1]);
TimerTask tT;
std::vector<taskinfo*> requests;
requests.reserve(1000);
for(int i=1; i <=5; i++ )
{
taskinfo* t = new taskinfo(i, [i]{ timeoutFunc(i); }, std::chrono::system_clock::now() + std::chrono::milliseconds(timeout));
tT.at(&t);
requests.push_back(t);
std::cout << "Request " << i << " Registered.... Time:" << std::chrono::system_clock::now().time_since_epoch().count() << std::endl;
}
while(1) sleep(60);
return 0;
}
答案 0 :(得分:1)
您正在将指针传递给不再存在的指针:
taskinfo* t = new taskinfo(i, [i]{ timeoutFunc(i); }, std::chrono::system_clock::now() + std::chrono::milliseconds(timeout));
tT.at(&t);
requests.push_back(t);
在上面的代码中,t
是为循环中的每次迭代实例化的局部变量。每次都会得到一个新的t
。
代码tT.at(&t);
获取此临时地址。
修复程序位于呼叫网站呼叫:tT.at(t);
。注意这就像requests.push_back(t);
此外:
//Execute a task when the timer times out
void TimerTask::at(taskinfo* task){
std::function<void()> threadFunc = [task]() { std::thread(task->func).detach(); };
task->func = threadFunc;
...
}