3

strace次のプログラムで実行する場合:

#include <boost/asio.hpp>
#include <pcap.h>

using namespace boost;

int main(int argc, char* argv[])
{
    asio::io_service io;
    asio::posix::stream_descriptor stream(io);
    char errorBuffer[BUFSIZ];
    pcap_t* p = pcap_open_live("any", BUFSIZ, false, 0, errorBuffer);
    stream.assign(pcap_get_selectable_fd(p));
    io.run();
    stream.close();
    pcap_close(p);
    return 0;
}

私は得る:

close(6)                                = 0
setsockopt(6, SOL_PACKET, PACKET_RX_RING, {block_size=0, block_nr=0, frame_size=0, frame_nr=0}, 16) = -1 EBADF (Bad file descriptor)
munmap(0xb733c000, 4145152)             = 0
close(6)                                = -1 EBADF (Bad file descriptor)

ご覧のとおり、closeは同じ上で 2 回呼び出されますfd(最初は によってstream.close()、次に によってpcap_close(p))。プログラムは意味をなさないかもしれませんが、 (閉じた での呼び出しstream.close()を防ぐため) と(で使用されるメモリを解放するため) の両方を呼び出す必要があります。これはマルチスレッド プログラムで発生します。io_serviceepoll_ctlfdpcap_close(p)pcap_t

close同じことをfd2回呼び出さずにこれを行う方法についてのアイデアはありますか?

4

1 に答える 1

5

Aposix::stream_descriptorは記述子の所有権を想定し、スコープ外になると記述子を閉じます。二重終了を解決するには、 を割り当てる前に記述子を複製しdup()ます。

于 2012-06-29T21:28:00.693 に答える