c - 如何检查 libpcap 中的数据包可用性

标签 c multithreading mutex libpcap

我使用 libpcap 来捕获数据包,我需要在有数据包可用时将数据包放入 FIFO 队列中。但是 FIFO 队列由 2 个线程共享,一个线程调用 pcap_next() 并将数据包放入 FIFO 队列。另一个线程从 fifo 队列中获取数据包。所以我必须将它与互斥体联系起来。如下所示:

u_char* pkt;
for(;;){
    pkt = pcap_next();
    lock(&mutex);
    some_process(pkt);
    insert(pkt, list);
    unlock(&mutext);
 }

pcap_next()与数据包缓冲区有关,如果缓冲区中没有数据包,则pcap_next()被阻塞。如果有数据包,则每次调用 pcap_next() 都会返回 1 个数据包。

对于每个加锁-解锁操作对,它只能取一个oen数据包,如果数据包到达不频繁,那么就可以了。但是如果数据包到达频繁,比如缓冲区中有很多待处理的数据包,那么对一个数据包进行加锁-解锁操作对会有点耗费资源。

我希望的是:在处理并插入数据包后,我可以立即检查数据包缓冲区中是否有数据包可用。如果有,继续处理插入。否则,解锁互斥量并返回循环。

有解决办法吗?

最佳答案

尝试类似的东西

/*
 * XXX - this can fail on some platforms and with some devices,
 * and there may be issues with select() on this.  See the
 * pcap_get_selectable_fd() man page for details.
 */
pcap_fd = pcap_get_selectable_fd(p);
pcap_setnonblock(p);  /* XXX - check for failure */

for (;;) {
    fd_set fdset;
    struct timeval timeout;

    /*
     * Wait for a batch of packets to be available.
     */
    FD_ZERO(&fdset);
    FD_SET(pcap_fd, &fdset);
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    if (select(1, &fdset, NULL, NULL, &timeout) == -1) {
        report an error;
    } else {
        lock(&mutex);
        pcap_dispatch(p, -1, callback, pointer-to-stuff);
        unlock(&mutex);
    }
}

这样,您锁定互斥体,处理整批数据包,然后解锁互斥体。许多 OS 捕获机制在一批中传送多个数据包,因此在这种情况下,每批将有一对锁定/解锁。

回调会做 some_process(pkt);insert(pkt, list); 的事情。

有可能,一旦您完成了一个批处理,下一个批处理将立即可用,因此这不会达到绝对最小的锁定/解锁对;然而,绝对最小值可能会在很长一段时间内锁定另一个线程,因此它永远无法取得任何进展,因此最好围绕每个批处理进行锁定和解锁。

关于c - 如何检查 libpcap 中的数据包可用性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16533442/

相关文章:

c - 即使有信号,fork/exec 也会离开僵尸进程

java - 当没有消费者准备好时处理生产者线程

Python线程和多处理错误?

.net - 如果在 VB.NET 中超时,如何停止/加入线程

c - TreeView fontsize - 自定义绘制或所有者绘制

C - 澄清 strtok 中的分隔符

c++ - 信号量(Mutex)的麻烦

c - 互斥体已经被我锁定了吗?

c - 如何在相互依赖的C文件中定义pthread和互斥锁?

FreeRTOS taskGetTickCount() 可以不被轮询吗?