我使用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个数据包。
它只能为每个锁定 - 解锁操作对获取一个数据包,如果数据包到达不频繁,则可以。但是如果数据包到达频繁,就像在缓冲区中存在许多未决数据包一样,为一个数据包提供锁定解锁操作对会消耗一些资源。
我希望:在处理和插入数据包之后,我立即可以检查数据包缓冲区中是否有可用的数据包。如果有,继续处理和插入。否则,解锁互斥锁并返回循环。
有解决方法吗?
答案 0 :(得分:1)
尝试诸如
之类的内容/*
* 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);
}
}
这样,您可以锁定互斥锁,处理整批数据包,然后解锁互斥锁。许多操作系统捕获机制批量传送多个数据包,因此在这种情况下每批将有一个锁定/解锁配对。
回调会执行some_process(pkt);
和insert(pkt, list);
内容。
一旦完成批处理,下一批可能会立即可用,因此无法实现绝对最小的锁定/解锁对;但是,绝对最小值可能会在很长一段时间内锁定另一个线程,因此它永远不会取得任何进展,因此锁定和解锁每个批处理可能是最好的。
答案 1 :(得分:0)
只使用pcap_dispatch(),或选择()使用非阻塞样式pcap_next()