我有一个允许用户扫描网络的GUI程序,问题是当调用pcap_loop函数时,我的GUI程序变得没有响应。(pcap_loop阻止当前线程)。
当我尝试使用pthread时,我在pcap_loop函数中遇到了一个SIGSEGV错误。为什么?就好像线程无法看到procPacket函数本身。
void procPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
//show packets here
}
void* pcapLooper(void* param)
{
pcap_t* handler = (pcap_t*) param;
pcap_loop(handler, 900 ,procPacket, NULL );
}
//some function that runs when a button is pressed
//handler has been opened through pcap_open_live
pthread_t scanner;
int t = pthread_create(&scanner,NULL,&pcapLooper, &handler );
if(t)
{
std::cout << "failed" << std::endl;
}
pthread_join(scanner,NULL);
//do other stuff.
答案 0 :(得分:3)
我强烈建议不要使用线程,除非你绝对不得不这样做。
问题是你必须非常小心,以避免竞争条件和其他同步问题。例如,您的GUI框架库可能不希望从多个线程调用,因此您的//show packets here
例程可能会使它混淆不清。
相反,我会建议,如果可能的话,从主线程中读取数据包。你没有说你正在使用哪个GUI框架;因为你正在使用C ++我会假设Qt,因为这很常见,但所有其他框架都有类似的功能。
您需要做的是:
(至于您的代码目前崩溃的原因 - 请注意,您可能希望将handler
而不是&handler
作为参数传递给pthread_create()
。但只是修复它可能会导致奇怪后来不可靠 - 所以单线程几乎肯定是前进的方向!)
答案 1 :(得分:1)
你需要更少的“&amp;”。假设
pcap_t *handle = pcap_open_live(...);使用
&handle
的将是pcap_t **
类型,但是您的线程函数会将其强制转换(顺便说一下,转换也是无意义/冗余)到pcap_t *
,这会导致未定义的行为使用它时,通常会出错。更好:
static void *pcap_looper(void *arg) { pcap_t *handle = arg; /* etc. */ return NULL; } int main(void) { pcap_t *handle; pthread_t tid; int ret; handle = pcap_open_live(...); ret = pthread_create(&tid, NULL, pcap_looper, handle); ... pthread_join(tid, NULL); return EXIT_SUCCESS; }