So far as I know about X11 with Xlib, is that with multi threading a programmer has 2 choices
Suppose i don't like first the first method with XInitThreads()
call. Why does second fail?
#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();
}
compiled with g++ -o xlib_multi xlib_multi.cpp -lX11 -std=c++11 -pthread -g
sometimes produces output:
Segmentation fault
or
No protocol specified
cannot connect to X server :0
Can it be, that I can't use XOpenDisplay() without thread-synchronization? But once the X11 connections are created with Xlib, I could use Xlib in multi-threaded environment without any problems? Is such assumption correct?
Or is Xlib just buggy for multi-threading anyway?
Chances are that XOpenDisplay() uses some global variable internally that is not thread-safe or shares data between the displays. I don't think it's wise to call XOpenDisplay like that from within a thread; I suggest opening the displays sequentially first, then start the threads with a Display pointer. Or protect the code section around XOpenDisplay (and XCloseDisplay!) with a mutex.
Either way, the fact that there is a separate XInitThreads() call makes your assumption that everything will be fine "after" XOpenDisplay() very dangerous.