【问题标题】:Xlib : Segmentation fault on multithreadingXlib:多线程的分段错误
【发布时间】:2019-05-15 12:31:47
【问题描述】:

我的尝试是为了实现三重缓冲方法而编写一个 Xlib 包装器。使用它,人们只需要计算他们的显示矩阵并将其转发给 API 进行显示。我有两个单独的线程来处理事件和显示。事件线程似乎可以毫无问题地执行,但是,显示线程与标准 Xlib 函数(如 XDrawRectangle、XFillArc、XSetForeground 等)一起使用时似乎会导致未知性质的分段错误。

这是我的线程执行部分:

int startx(){
    pthread_t eventsThread, displayThread;
    char msg1[15] ="Events Thread", msg2[15] = "Display Thread";
    int pid1, pid2;
    pid1 = pthread_create( &eventsThread, NULL, eventsHandler, (void*) msg1);
    pid2 = pthread_create( &displayThread, NULL, displayHandler, (void*) msg2);
    pthread_join(eventsThread, NULL);
    pthread_join(displayThread, NULL); 
    return 0;
};

这是我的 displayHandler :

void *displayHandler(void* args){
    cout<<connectionNumber<<endl;
    Color c(50,50,250);
    int width = 40, height = 60,x = 500, y = 100;
    for(int i=0;i<1300;i++){
        XSetForeground(display, xgraphics, c.decimal);
        XDrawRectangle(display, mainWindow, xgraphics, x, y, width, height);
        XFlush(display);
    }
}

eventsThread 似乎正在执行而没有错误。另外,我尝试将显示功能作为主程序的一部分,结果相同。

如果有人能告诉我使用矩阵绘制窗口的替代/正确方法,将不胜感激。

注意:Color 是一个自制类,便于颜色计算。

【问题讨论】:

  • void *displayHandler(void* args) 应该可能是return NULL; 但我不知道缺少返回是否导致问题。另外:你有 C++11(或更高版本)吗?如果是这样,请查看标准 &lt;thread&gt; 库。
  • 在使用线程之前你会调用XInitThreads吗?此函数初始化 Xlib 对并发线程的支持,并且必须是多线程程序调用的第一个 Xlib 函数。
  • @Siliace 在线程创建或执行之前调用 XInitThreads 没有影响。
  • 您在处理程序中使用的全局变量是否在多个线程中使用?如果是,X-functions 线程是否安全?
  • @TedLyngmo 编写互斥锁解决了这个问题。感谢您指出这个基本错误。它现在可以正常工作。也无需使用线程库。

标签: c++ animation segmentation-fault pthreads xlib


【解决方案1】:

这对我来说在 howdy 行之前崩溃了。取消注释 return NULL; 行使其工作。

#include <iostream>
#include <pthread.h>

void *displayHandler(void* args) {
    char* txt = reinterpret_cast<char*>(args);
    std::cout << txt << "\n";
    // return NULL;
}

int startx(){
    pthread_t displayThread;
    char msg2[15] = "Display Thread";
    int pid2;
    pid2 = pthread_create( &displayThread, NULL, displayHandler, (void*) msg2);
    pthread_join(displayThread, NULL);
    return 0;
}

int main() {
    startx();
    std::cout << "howdy\n";
}

【讨论】:

  • 标准函数运行良好。是 XLib 函数没有。
  • @SupratikChatterjee 好的。那么,添加return NULL; 没有任何效果?
  • 绝对没有。没有区别。
  • @SupratikChatterjee 好的,但无论如何都要保留它。如果你不这样做,那就是 UB。
  • 好的,在这种情况下,我的事件线程也会这样做。谢谢。
【解决方案2】:

正如 Ted Lyngmo 指出的那样。问题在于 Xlib 没有为写入显示器实现线程安全。因此,编写互斥锁提供了一个解决方案。

如果将任何事件掩码设置为写入屏幕,则两者的单独线程将变得毫无意义。而是让掩码切换变量,让它们同时工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 2016-02-09
    • 2011-03-17
    • 2018-11-02
    • 2015-09-10
    相关资源
    最近更新 更多