Asynchronous 类实例的pthread未启动

Asynchronous 类实例的pthread未启动,asynchronous,io,pthreads,boost-asio,c++98,Asynchronous,Io,Pthreads,Boost Asio,C++98,注意:C++98 timerThread,NULL,run_io,&dbInstance->io_服务); 标准::cout io_服务); //pthread_join(&dbInstance->timerThread,NULL); } 返回*dbInstance; } }; 数据库.cpp Database*数据库::dbInstance=NULL; 数据库::数据库() :interval(2000),timer(io_服务,interval){} 数据库::~数据库() { sqlit

注意:C++98

<我是一个刚到C++的新手,我正在编写一个数据库程序,我正试图使用pToX使用Boosi::asIO包启动计时器。计时器的目的是在sql查询被放入缓冲区后启动,如果在一段时间内没有收到任何消息,缓冲区将运行执行函数。我已经设法将其编译,但看起来pthread实例并没有启动

我在getInstance方法中调用了pthread,相应地设置了boost::asio报警。我将在下面展示的是,通过调用
io\u run()
直接启动计时器,计时器会在警报中进入一个循环

数据库.h

void*运行io(void*arg);
类数据库
{
私人:
静态数据库*dbInstance;//=NULL;
公众:
boost::asio::io_服务io_服务;
升压::posix_时间::毫秒间隔;
boost::asio::截止期计时器;
pthread_t timerThread;
公众:
静态数据库&getInstance()
{
如果(!dbInstance)
{
dbInstance=新数据库();
//pthread_创建(&dbInstance->timerThread,NULL,run_io,&dbInstance->io_服务);
标准::cout io_服务);
//pthread_join(&dbInstance->timerThread,NULL);
}
返回*dbInstance;
}
};
数据库.cpp

Database*数据库::dbInstance=NULL;
数据库::数据库()
:interval(2000),timer(io_服务,interval){}
数据库::~数据库()
{
sqlite3_关闭(db);
}
无效数据库::setAlarm(常量boost::系统::错误代码&/*e*/)
{

std::cout我非常不明白为什么任何使用Boost或C++11(或两者)的人都会使用原始
pthread
线程(请参见示例以获得良好的并置)

真正的问题可能是
io\u服务
的工作即将结束(参见示例)

如果没有挂起的异步操作,线程将退出

另一个问题是数据的准确性问题

timer.expires_at(timer.expires_at() + interval);
可能有些处理程序花费了太多的时间,以至于在您计划下一次报警时,截止日期已经过了。使用它可能更好

timer.expires_from_now(interval);
注意,这也与注释更匹配。注释已经受到注释的影响,因为它表示“1秒”,但实际上它是某个定义的常量
DB\u WRITE\u TIME

或者以其他方式将计时器与其他处理程序分开,以保证准确的调度

最后,由于没有任何关机操作,您不得不关闭。静态实例永远不会被破坏,但值得注意的是,未分离的线程永远不会被连接,从而在关机时创建未定义的行为

这个问题实际上与最近在这里讨论的问题几乎相同,在这里我还更详细地解释了
工作方式
警卫的工作方式:

下面是一个c++11重写和必要的修复:

因为我现在注意到你是因为某种奇怪的原因被困在c++03中的人,一个Boost线程版本:

C++03演示/增强线程

#include <boost/asio.hpp>
#include <boost/make_shared.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/thread.hpp>
#include <iostream>

static const int DB_WRITE_TIME = 500;

class Database
{
  private:
    static boost::shared_ptr<Database> dbInstance;

    Database()
        : work(new io_service::work(io)),
          interval(750),
          timer(io, interval)
    {
        std::cout << "INSTANCE CREATED" << std::endl;
    }

    void on_timer_completed(const boost::system::error_code& ec) {
        std::cout << "[on_timer_completed] " << ec.message() << std::endl;

        if (!ec) {
            boost::posix_time::milliseconds interval(DB_WRITE_TIME);

            // Reschedule the timer
            timer.expires_from_now(interval);
            timer.async_wait(boost::bind(&Database::on_timer_completed, this, _1));
        }
    }

    int buffer()
    {
        // DO BUFFER STUFF

        timer.expires_from_now(interval);
        timer.async_wait(boost::bind(&Database::on_timer_completed, this, _1));
        // io_service.run() <-- uncommenting this results in the loop
        return 1; // rc ;
    }

  public:
    void do_stuff() {
        buffer(); // whatever it does
    }

    void teardown() {
        std::cout << "INSTANCE SHUTTING DOWN\n";
        timer.cancel(); // stop timer loop
        work.reset();   // allows io.run() to exit
        if (timerThread.joinable()) {
            timerThread.join(); // releasing the bound shared_ptr
        }
        dbInstance.reset(); // releasing the instance
    }

    ~Database() {
        //sqlite3_close(db);
        std::cout << "INSTANCE DESTROYED\n";
    }

  private:
    typedef boost::asio::io_service io_service;
    io_service io;
    boost::scoped_ptr<io_service::work> work;
    boost::posix_time::millisec interval;
    boost::asio::deadline_timer timer;
    boost::thread timerThread;

    void run_io() {
        std::cout << "ENTER IO THREAD" << std::endl;
        io.run();
        std::cout << "LEAVE IO THREAD" << std::endl;
    }
public:
    static Database &getInstance()
    {
        if (!dbInstance)
        {
            dbInstance.reset(new Database());
            dbInstance->timerThread =
                boost::thread(boost::bind(&Database::run_io, dbInstance));
        }
        return *dbInstance;
    }
};

boost::shared_ptr<Database> Database::dbInstance;

int main() {
    Database& db = Database::getInstance();
    boost::this_thread::sleep_for(boost::chrono::seconds(1));

    db.do_stuff();
    boost::this_thread::sleep_for(boost::chrono::seconds(3));
    // ....

    db.teardown();
}

嘿,Sehe,非常感谢你的解释。我已经做了你建议的更改,但是看起来仍然没有出于某种原因调用报警处理程序。我输入了一些调试打印,并看到
timer.expires\u的返回从现在开始(间隔)
0
开始,然后作为整个程序的
1
循环,不调用报警处理程序。
INSTANCE CREATED
ENTER IO THREAD
[on_timer_completed] Success
[on_timer_completed] Success
[on_timer_completed] Success
[on_timer_completed] Success
[on_timer_completed] Success
INSTANCE SHUTTING DOWN
[on_timer_completed] Operation canceled
LEAVE IO THREAD
INSTANCE DESTROYED