我使用libpcap来捕获数据包,一旦有数据包可用,我就需要将数据包放入FIFO队列。但是先进先出队列是由两个线程共享的,一个线程调用pcap_next()并将数据包放入先进先出队列。另一个线程从fifo队列获取数据包。所以我不得不把它和一个互斥锁联系起来。如下所示:
u_char* pkt;
for(;;){
pkt = pcap_next();
lock(&mutex);
some_process(pkt);
insert(pkt, list);
unlock(&mutext);
}pcap_next()与数据包缓冲区相关,如果缓冲区中没有数据包,则阻塞pcap_next()。如果有/有数据包,每次调用pcap_next()都会返回一个数据包。
它只能为每个锁定-解锁操作对获取一个oen包,如果包不是频繁到达,那么它是可以的。但是,如果数据包频繁到达,例如在缓冲区中有许多挂起的数据包,则对一个数据包执行锁定-解锁操作对有点消耗资源。
我希望的是:在处理和插入数据包后,我可以立即检查数据包缓冲区中是否有可用的数据包。如果有,则继续处理和插入。否则,解锁互斥锁并返回循环。
有解决这个问题的办法吗?
发布于 2013-05-15 00:22:52
只需使用pcap_dispatch(),或者使用非阻塞样式的pcap_next()
发布于 2015-03-27 05:07:16
尝试一些东西,比如
/*
* 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);
}
}callback会做some_process(pkt);和insert(pkt, list);之类的事情。
有可能,一旦您完成了一个批处理,下一个批处理将立即可用,因此这不能达到锁定/解锁对的绝对最小值;然而,绝对最小值可能会锁定另一个线程很长一段时间,因此它永远不会取得任何进展,因此锁定和解锁每个批处理可能是最好的。
https://stackoverflow.com/questions/16533442
复制相似问题