2013-10-07 7 views
0

xlib, pthread 및 cairo를 사용하여 muti-thread 프로그램을 작성하고 있습니다. 이 프로그램은 클릭 이벤트 후 10 포인트를 그리기 위해 스레드를 만듭니다.Xlib Muti 스레드 프로그램은 strace에서만 작동합니다.

문제는 :

프로그램이 세 점을 그린 후에는

X Error of failed request: BadRequest (invalid request code or no such operation) 
    Major opcode of failed request: 0() 
    Serial number of failed request: 67 
    Current serial number in output stream: 97 

그러나 추락하는 Xlib 불만있어

, 그것이 내가 "strace를 같은 strace를 사용하고 때 제대로 작동 할 수 있습니다 ./ a.out ".

여기에 내 코드 클립입니다 :

void *draw_point(void *arg) { //paint random-postion point 
    int i = 0; 
    int seed; 
    double x ,y; 
    srand(seed); 
    cairo_set_source_rgba (cairo, 1, 0.2, 0.2, 0.6); 
    for(i = 0; i< 10; i++) { 
     x = rand() % 200; 
     y = rand() % 200; 
     if(candraw) { 
      cairo_arc (cairo, x, y, 10.0, 0, 2*M_PI); 
      cairo_fill (cairo); 
     } 
     hasdraw = true; 
     sleep(1); 
    } 
    return NULL; 
} 

bool win_main(void) 
{ 
    int clickx = 0, clicky = 0; 
    unsigned long valuemask; 
    XEvent event; 

    valuemask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask; 

    XSelectInput(display, win, valuemask); 

    pthread_t thread; 

    while (1) { 
     while (XPending(display) == 0) { 
      candraw = true; 
      if(hasdraw) 
      XFlush(display); 
      candraw = false; 
     } 
     XNextEvent(display, &event); 
     candraw = false; 
     switch (event.type) { 
     case MotionNotify: 
      //... 
      break; 
     case ButtonPress: 
      clickx = event.xbutton.x; 
      clicky = event.xbutton.y; 
      if(clicky < 50) 
       pthread_create(&thread, NULL, draw_point, NULL); 
      break; 
     case ButtonRelease: 
      //... 
      break; 
     default: 
      break; 
     } 
    } 
    return 0; 
} 

사람이 이상한 문제에 대한 아이디어를 가지고 있습니까? 감사합니다.

답변

1

이 문제는 2 개의 스레드가 디스플레이에 동시에 액세스하려고하는 멀티 스레딩을 사용하여 발생합니다.

strace는 타이밍을 변경하므로 스레드가 다른 시간에 디스플레이에 액세스합니다.

Xlib에는 충돌을 방지하는 기능이 있습니다. 스레드 지원을 활성화하는 XInitThreads를 조회하고 디스플레이에 액세스하기 전후의 각 스레드에서 호출해야하는 XLockDisplay 및 XUnlockDisplay.