我使用 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/