C++ 使用boost:asio和select?阻止TCP输入或文件更新

C++ 使用boost:asio和select?阻止TCP输入或文件更新,c++,boost,boost-asio,C++,Boost,Boost Asio,我本来打算在我的程序中有一个线程,它将等待两个文件描述符,一个用于套接字,另一个用于描述文件系统的FD,专门等待查看是否将新文件添加到目录。因为我希望很少看到添加的新文件或新的TCP消息进入,所以我希望有一个线程等待输入,并在出现输入时处理检测到的输入,而不是使用单独的线程 我终于明白了!得到“老板”的许可使用boost。所以现在我想用boost:asio替换基本插座。只是我遇到了一个小问题。似乎asio实现了自己版本的select,而不是提供一个可以直接与select一起使用的FD。这让我无法

我本来打算在我的程序中有一个线程,它将等待两个文件描述符,一个用于套接字,另一个用于描述文件系统的FD,专门等待查看是否将新文件添加到目录。因为我希望很少看到添加的新文件或新的TCP消息进入,所以我希望有一个线程等待输入,并在出现输入时处理检测到的输入,而不是使用单独的线程


我终于明白了!得到“老板”的许可使用boost。所以现在我想用boost:asio替换基本插座。只是我遇到了一个小问题。似乎asio实现了自己版本的select,而不是提供一个可以直接与select一起使用的FD。这让我无法确定如何在两种情况下都阻止新文件和TCP输入,同时其中一种情况仅适用于select,而另一种情况似乎不支持使用select。有没有一个简单的方法可以解决我所缺少的问题?

ASIO最好是异步使用,这就是它的含义:您可以为TCP读取和文件描述符活动设置处理程序,这些处理程序将为您调用

下面是一个演示示例,让您开始使用inotify支持编写Linux:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <sys/inotify.h>

namespace asio = boost::asio;
void start_notify_handler();
void start_accept_handler();

// this stuff goes into your class, only global for the simplistic demo
asio::streambuf buf(1024);
asio::io_service io_svc;
asio::posix::stream_descriptor stream_desc(io_svc);
asio::ip::tcp::socket sock(io_svc);
asio::ip::tcp::endpoint end(asio::ip::tcp::v4(), 1234);
asio::ip::tcp::acceptor acceptor(io_svc, end);

// this gets called on file system activity
void notify_handler(const boost::system::error_code&,
                    std::size_t transferred)
{
    size_t processed = 0;
    while(transferred - processed >= sizeof(inotify_event))
    {
        const char* cdata = processed
                            + asio::buffer_cast<const char*>(buf.data());
        const inotify_event* ievent =
                                 reinterpret_cast<const inotify_event*>(cdata);
        processed += sizeof(inotify_event) + ievent->len;
        if(ievent->len > 0 && ievent->mask & IN_OPEN)
            std::cout << "Someone opened " << ievent->name << '\n';
    }
    start_notify_handler();
}

// this gets called when nsomeone connects to you on TCP port 1234
void accept_handler(const boost::system::error_code&)
{
    std::cout << "Someone connected from " 
              << sock.remote_endpoint().address() << '\n';
    sock.close(); // dropping connection: this is just a demo
    start_accept_handler();
}

void start_notify_handler()
{
    stream_desc.async_read_some( buf.prepare(buf.max_size()),
        boost::bind(&notify_handler, asio::placeholders::error,
                    asio::placeholders::bytes_transferred));
}

void start_accept_handler()
{
    acceptor.async_accept(sock,
        boost::bind(&accept_handler, asio::placeholders::error));
}

int main()
{
    int raw_fd = inotify_init(); // error handling ignored
    stream_desc.assign(raw_fd);
    inotify_add_watch(raw_fd, ".", IN_OPEN);
    start_notify_handler();
    start_accept_handler();
    io_svc.run();
}

库比:很好的例子。谢谢。愚蠢的问题:既然我们注册了两个异步读取,那么这是否意味着正在处理的一个异步事件可能会被另一个异步事件的到来打断?这就是为什么存在的原因吗?@decimusphostle它不会被打断。如果池中的所有线程都忙,新事件将在另一个线程上运行或在asio的队列中等待。在这个例子中,只有一个线程被添加到asio的池中。但是,此程序无法获得文件创建/删除/修改事件的通知。在目录中添加一个手表似乎也没有什么帮助。为了进一步调试这个,我去掉了asio代码,并编写了一个。有什么想法/意见吗?蒂亚。@decimusphostle你试过我的例子了吗?它适用于我,基于多年来大量使用的生产代码。我在代码中看到的一件事是,您正在查看一个文件,但忽略了len字段为零的事件,这是针对文件的。我来看看你的帖子。