2012-04-15 3 views
1

저는 pthread 및 xlib 프로그래밍이 새로 도입되었습니다. 무승부를 시도하고 반대 방향으로 두 세트의 직사각형을 이동하려고하지만 내 코드를 실행할 때 스레드 중 하나만 실행되고 다른 하나는 무시됩니다.Pthread Xlib 프로그래밍

몇 가지 옵션을 시도했지만 아무 소용이 없습니다. 모든 제안을 주시면 감사하겠습니다.

내 소스 코드를 포함 시켰습니다.

감사합니다.

컴파일 : gcc가 -o demofinal을 Demofinal.c -lpthread -lX11

실행 : ./Demofinal

#include <stdio.h> 
#include <stdlib.h> 
#include <X11/Xlib.h> 
#include <X11/Xutil.h> 
#include <X11/Xos.h> 
#include <X11/Xatom.h> 
#include <X11/keysym.h> 
#include <pthread.h> 
//Compile gcc -o Demofinal Demofinal.c -lpthread -lX11 
//Run ./Demofinal 

Display *dis; 
Window win; 
XEvent report; 
GC green_gc; 
XColor green_col; 
Colormap colormap; 
pthread_mutex_t mutexsum; 

char green[] = "#00FF00"; 
void *createMoveLogs(void *ptr); 
typedef struct str_thdata 
{ 
int xval; 
int yval; 
int dir; 
} thdata; 

int main() { 

pthread_t mvleft, mvright; 
thdata data1, data2;   

/* initialize data to pass to thread 1 and 2*/ 
    data1.xval = 600; 
    data1.yval = 115; 
    data1.dir = 0; 

    data2.xval = 5; 
    data2.yval = 250; 
    data2.dir = 1; 



dis = XOpenDisplay(NULL); 
win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 550, 550, 0, WhitePixel (dis, 0), WhitePixel(dis, 0)); 
XMapWindow(dis, win); 
colormap = DefaultColormap(dis, 0); 
green_gc = XCreateGC(dis, win, 0, 0); 
XParseColor(dis, colormap, green, &green_col); 
XAllocColor(dis, colormap, &green_col); 
XSetForeground(dis, green_gc, green_col.pixel); 

pthread_create(&mvleft, NULL, createMoveLogs, (void*) &data1);//thread 1 move right to left 
pthread_create(&mvright, NULL, createMoveLogs, (void*) &data2);//thread 2 move left to right 
pthread_join(mvleft, NULL); 
pthread_join(mvright, NULL);  
return 0; 
    } 

    void *createMoveLogs(void *ptr) 
    { 
thdata *data;    
    data = (thdata *) ptr; 

    int x= data->xval; int y = data->yval; int i; 
int direction = data->dir; 
//check if the direction to move == left 
if(direction == 0){ 
    pthread_mutex_lock(&mutexsum); 
    for(i=0; i<=600; i++){ 
     XDrawRectangle(dis, win, green_gc, x, y, 145, 50); 
     XDrawRectangle(dis, win, green_gc, x+200, y, 145, 50); 
     XDrawRectangle(dis, win, green_gc, x+400, y, 145, 50); 
     x-=10; 
     if (x==-500){x=data->xval; i=0;} 

     usleep(100000); 
     XFlush(dis); 
     XClearWindow(dis, win); 
    } 
pthread_mutex_unlock(&mutexsum); 
}else if(direction == 1){ 
    pthread_mutex_lock(&mutexsum); 
    for(i=0; i<=600; i++){ 

     XDrawRectangle(dis, win, green_gc, x, y, 145, 50); 
     XDrawRectangle(dis, win, green_gc, x-200, y, 145, 50); 
     XDrawRectangle(dis, win, green_gc, x-400, y, 145, 50); 
     x+=10; 
     if (x==855){x=5; i=0;} 
     usleep(100000); 
     XFlush(dis); 
     XClearWindow(dis, win); 
    } 
    pthread_mutex_lock(&mutexsum); 
    } 
    } 
+1

한 번에 하나의 스레드 만 X11 호출을 할 수 있습니다. –

+0

@BasileStarynkevitch 그래서 내가하려는 것은 불가능할 것입니다. 또는 어떤 제안이 있습니까? – fanbondi

+0

사실, Xlib 호출을하는 단 하나의 스레드 만 있으면 좋습니다. GTK 또는 QT와 같은 툴킷을 사용하면 메인 스레드 만 GUI 호출을 수행 할 수 있습니다. X11을 여러 스레드에서 처리하고 싶다면 직렬화에 뮤텍스를 사용하고 종종 Xsync를 호출하는 것을 잊지 마십시오. –

답변

0

당신은 루프와 usleep() 통화 뮤텍스 잠금 내부 는 의미가 실행할 첫 번째 스레드는 다른 스레드를 영원히 잠급니다.

+0

@geekosuar 그게 내가 한 마지막 시도 였어. 뮤텍스가 없어도 똑같이 유지됩니다. 고마워요. – fanbondi

+1

뮤텍스가 없다면 어디에서나 XInitThreads()가 보이지 않기 때문에 핵심 덤프를 얻지 못할 수도 있습니다. Xlib은 실제로 threadsafe가 아닙니다. 당신은 스레드를 전혀 사용하지 않는 것이 가장 좋습니다. – geekosaur

1

다른 스레드를 호출하기 전에 XInitThreads()을 호출하기 전에 Xlib은을 호출하기 전에 작동합니다. 그것으로도 여전히 몇 가지 버그가 있지만 스레드가 없으면 스레드간에 적절한 잠금 또는 동기화를 시도하지 않습니다.

2

실행하지 마십시오. 빛이 깜박이는 것이 좋습니다.

XInitThreads(); 
... 

if(direction == 0){ 
    for(i=0; i<=600; i++){ 
     pthread_mutex_lock(&mutexsum); 
     printf ("Thread %d\n", direction); 
     XDrawRectangle(dis, win, green_gc, x, y, 145, 50); 
     XDrawRectangle(dis, win, green_gc, x+200, y, 145, 50); 
     XDrawRectangle(dis, win, green_gc, x+400, y, 145, 50); 
     x-=10; 
     if (x==-500){x=data->xval; i=0;} 

     XFlush(dis); 
     XClearWindow(dis, win); 
     usleep(50000); 
     pthread_mutex_unlock(&mutexsum); 
     usleep(50000); 
    } 
}else if(direction == 1){ 
    for(i=0; i<=600; i++){ 
     pthread_mutex_lock(&mutexsum); 
     printf ("Thread %d\n", direction); 
     XDrawRectangle(dis, win, green_gc, x, y, 145, 50); 
     XDrawRectangle(dis, win, green_gc, x-200, y, 145, 50); 
     XDrawRectangle(dis, win, green_gc, x-400, y, 145, 50); 
     x+=10; 
     if (x==855){x=5; i=0;} 
     XFlush(dis); 
     XClearWindow(dis, win); 
     usleep(50000); 
     pthread_mutex_unlock(&mutexsum); 
     usleep(50000); 
    } 
} 

이렇게하면 두 세트의 이동 사각형이 모두 표시됩니다. 물론이 방법은 완전히 야만적입니다. XClearWindow()은 계속 깜박입니다. 실제 프로그램에서 각 스레드는 다른 프레임의 부분을 건드리지 않고 이전 프레임의 자체 부분을 지우는 역할을합니다.