2012-04-15 14 views
1

私はpthreadとxlibのプログラミングにはとても新しいです。 2つの四角形を反対方向に描画して移動しようとしていますが、私のコードを実行するとスレッドのうちの1つだけが実行され、もう1つは無視されます。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

一度に1つのスレッドだけがX11コールを行うことができます –

+0

@BasileStarynkevitchだから、私がしようとしていることは不可能でしょうか?または何か提案がありますか? – fanbondi

+0

実際、Xlib呼び出しを行うスレッドは1つだけとすることをお勧めします。 GTKやQTのようなツールキットでは、メインスレッドだけがGUI呼び出しを行うことができます。あなたが絶対にX11をやっているいくつかのスレッドを持っていたいなら(私には間違っています)、シリアライゼーションにはミューテックスを使い、Xsyncを頻繁に呼び出すことを忘れないでください。 –

答えて

0

あなたがいることを意味し、ループとusleep()通話mutexロックの内部を持っています実行する最初のスレッドは、他のスレッドを永久にロックします。

+0

@geekosuarそれは私がやった最後のものでした。ミューテックスなしでも同じままです..ありがとうございます。 – fanbondi

+1

ミューテックスがなければ、どこにでもXInitThreads()が表示されないので、コアダンプを取得できないのは幸いです。 Xlibは実際にスレッドセーフではありません。スレッドをまったく使用しようとしない方がよいでしょう。 – geekosaur

1

複数スレッドからの呼び出しのためのXlibのサポートは、他のXlib関数を呼び出す前にXInitThreads()より前にを呼び出す場合にのみ機能します。それでも、まだいくつかのバグがありますが、それがなければ、スレッド間の適切なロックや同期をとる試みはありません。

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()は一定のちらつきを引き起こします。実際のプログラムでは、各スレッドは、他の部分に触れることなく、古いフレームのそれ自身の部分をクリアする責任があります。