2014-12-02 81 views
1

我有两个线程,每个线程同时从相同的偏差数据包捕获,但当第二个线程到达pcap_compile()函数时,程序崩溃。另外每个线程都有自己的变量,并且不使用全局变量。看起来他们得到了相同的设备句柄,因此程序崩溃了。为什么我需要两个线程?因为我想单独发送和接收指定的pcap过滤器上的数据包。那么我该如何解决这个问题?或者使用一个线程并使用tcp头中的地址手动对发送和接收的数据包进行排序,会更好吗?两个pcap_compile()在同一个设备上?

回答

1

pcap_compile是不是线程安全。您必须围绕所有对可能由独立线程使用临界区/互斥体遇到的调用进行调用,以防止因编译表达式的解析器中的非线程安全状态而导致的错误(对于血腥细节,它使用YACC创建代码解析表达式和为此生成的代码显然不是线程安全的)。

如果你在多个线程中重复使用相同的设备句柄,那么你需要为每个线程明确地打开一个设备,这个线程就是你不需要的。你应该在你打算使用它的线程中打开pcap句柄,因此每个计划进行捕获的线程都应该自己做pcap_open

看守调用pcap_compile一个关键部分,你可以创建一个简单的包装(C++的窗口封装关键部分):

class lock_interface { 
public: 
    virtual void lock() = 0; 
    virtual void unlock() = 0; 
}; 

class cs : public lock_interface { 
    CRITICAL_SECTION crit; 
public: 
    cs() { InitializeCriticalSection(&crit); } 
    ~cs() { DeleteCriticalSection(&crit); } 
    virtual void lock() { 
     EnterCriticalSection(&crit); 
    } 
    virtual void unlock() { 
     LeaveCriticalSection(&crit); 
    } 
private: 
    cs(const locker &); 
    cs &operator=(const cs &); 
}; 

class locker { 
    lock_interface &m_ref; 
public: 
    locker(lock_interface &ref) : m_ref(ref) { m_ref.lock(); } 
    ~locker() { m_ref.unlock(); } 
private: 
    locker(const locker &); 
    locker &operator=(const locker &); 
}; 

static cs section; 

int 
wrapped_pcap_compile(pcap_t *p, struct bpf_program *fp, const char *str, int optimize, bpf_u_int32 netmask) 
{ 
    locker locked(section); 
    pcap_compile(p, fp, str, optimize, netmask); 
} 
相关问题