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

Xlib fails (Segmentation fault) even with each connection per thread

就我对 X11 和 Xlib 的了解而言,对于多线程,程序员有 2 个选择

  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 server\n");
        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++ -o xlib_multi xlib_multi.cpp -lX11 -std=c++11 -pthread -g

有时会产生输出:

Segmentation fault

No protocol specified
cannot connect to X server :0

难道我不能在没有线程同步的情况下使用 XOpenDisplay() 吗?但是一旦用 Xlib 创建了 X11 连接,我就可以在多线程环境中毫无问题地使用 Xlib 了吗?这样的假设是否正确?

或者 Xlib 只是用于多线程的 bug 吗?

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

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