1

私は pthread と xlib プログラミングに非常に慣れていません。2セットの長方形を反対方向に描画して移動しようとしていますが、コードを実行すると、スレッドの1つだけが実行され、もう1つは無視されます。

いくつかのオプションを試しましたが、役に立ちませんでした。任意の提案をいただければ幸いです。

ソースコードを含めました。

ありがとう。

コンパイル: 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);
  }
   }
4

3 に答える 3

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

于 2013-06-18T21:10:44.197 に答える
1

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

于 2013-06-18T02:38:17.900 に答える
0

ミューテックスロック内にループとusleep()呼び出しがあります。つまり、最初に実行するスレッドが他のスレッドを永久にロックアウトします。

于 2012-04-15T07:25:34.263 に答える