即使每个线程都有连接,Xlib也会失败(分段错误)



据我所知,X11与Xlib,是与多线程程序员有两个选择

  1. 尽早调用XInitThreads
  2. 或为每个线程使用新连接(XOpenDisplay)。

假设我不喜欢第一个方法与XInitThreads()调用。为什么第二个失败了?

#include <X11/Xlib.h>
#include <thread>

void startBasicWin() {
    Display *display;
    if ( (display=XOpenDisplay(NULL)) == NULL )
    {
        fprintf( stderr, "cannot connect to X servern");
        exit( -1 );
    }
    XCloseDisplay(display);
}
int main() {
    std::thread t3 = std::thread(startBasicWin);
    std::thread t4 = std::thread(startBasicWin);
    std::thread t5 = std::thread(startBasicWin);
    std::thread t6 = std::thread(startBasicWin);
    std::thread t7 = std::thread(startBasicWin);
    std::thread t8 = std::thread(startBasicWin);
    std::thread t9 = std::thread(startBasicWin);
    t3.join();
    t4.join();
    t5.join();
    t6.join();
    t7.join();
    t8.join();
    t9.join();
}

编制g++ - 0 xlib_multi xlib_multi.cpp -lX11 -std= g++ -pthread -g

有时产生输出:

Segmentation fault

No protocol specified
cannot connect to X server :0

可以是,我不能使用XOpenDisplay()没有线程同步?但是,一旦用Xlib创建了X11连接,我就可以在多线程环境中使用Xlib而不会出现任何问题。这样的假设正确吗?

或者Xlib只是多线程的bug ?

有可能XOpenDisplay()在内部使用一些不线程安全的全局变量或在显示之间共享数据。我不认为这是明智的调用XOpenDisplay这样从线程内;我建议先顺序打开显示,然后用显示指针启动线程。或者用互斥锁保护XOpenDisplay(和XCloseDisplay!)周围的代码段。

无论哪种方式,有一个单独的XInitThreads()调用的事实使您的假设一切都会很好"之后"XOpenDisplay()是非常危险的。

最新更新