0

私は pthread を使って C でちょっとしたゲームをしています。数字で表される文字を持つマトリックス(intの2dテーブル)があります(3,4,5、その他の数字はスレッドではありません)。それらのキャラクターは、私のマトリックス内で移動する必要があります。 serveurAffテーブルを表示するために使用されます。

tabDtabCrimおよびtabJournalisteグローバルです。それらはすべてポインターです。

ここに私のコードmain

int statut, i,arg[2];
while (!serveurAff.fin)
    pthread_cond_wait(&serveurAff.termine, &serveurAff.mutex);
serveurAff.reqATraiter = 1;
serveurAff.fin = 0;
pthread_cond_signal(&serveurAff.requete);
pthread_mutex_unlock(&serveurAff.mutex);
//detective thread
for(i = 0; i < 3; i++){
    arg[0] = tabD[i]->posY;
    arg[1] = tabD[i]->posX;
    printf("test1 \n ");
    statut = pthread_create(&tabD[i]->threaddete, NULL, routinePersonne, (void *) &arg);
}
//criminel thread
for(i = 0; i < 5; i++){
    arg[0] = tabCrim[i]->posY;
    arg[1] = tabCrim[i]->posX;
    printf("test2 \n ");
    statut = pthread_create(&tabCrim[i]->threadcrim, NULL, routinePersonne, (void *) &arg);
}
//thread journaliste
for(i = 0; i < 3; i++){
    arg[0] = tabJournaliste[i]->posY;
    arg[1] = tabJournaliste[i]->posX;
    printf("test3 \n ");
    statut = pthread_create(&tabJournaliste[i]->threadjour, NULL, routinePersonne, (void *) &arg);
}
pthread_join(threadAff, NULL);

printfpthread を開始する前に a を書くと、 「いくつかの繰り返し」の位置は問題ありません

   test1 
 test1 
 test1 
 test2 
 test2 
 test2 
 test2 
 test2 
 test3 
 test3 
 test3 
 coord1 => 9, coord0, 1 
xancien => 9 yancien => 1 
coord1 => 20, coord0, 7 
xancien => 20 yancien => 7 
azazaz









Etape 0
01   5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
02   0 4 4 4 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 
03   0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
04   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 
05   0 0 3 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 
coord1 => 2, coord0, 4 
xancien => 2 yancien => 4 
coord1 => 0, coord0, 0 
coord1 => 20, coord0, 7 
xancien => 20 yancien => 7 
coord1 => 23, coord0, 4 
xancien => 23 yancien => 4 
xancien => 0 yancien => 0 
coord1 => 0, coord0, 0 
xancien => 0 yancien => 0 
coord1 => 20, coord0, 7 
xancien => 20 yancien => 7 
06   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 
07   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
08   0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 5 0 3 0 0 0 3 0 0 
09   0 0 0 0 0 0 0 0 0 0 0 5 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
coord1 => 23, coord0, 4 
xancien => 23 yancien => 4 
coord1 => 0, coord0, 0 
xancien => 0 yancien => 0 
coord1 => 0, coord0, 0 
xancien => 0 yancien => 0 
coord1 => 0, coord0, 0 
xancien => 0 yancien => 0 

いくつかの反復の後、すべての値が 0 であることがわかります...そして、スレッドを開始する前に書き込みを行わないprintf("test1")と、値は常に 0 になります。

ここにの一部routinePersonne

void *routinePersonne(void *arg) {
while (1){
int* coord = (int*)arg;     
        int xancien = coord[1]; 
        int yancien = coord[0];
        printf("coord1 => %d, coord0, %d \n",xancien,yancien);
        printf("xancien => %d yancien => %d \n",xancien,yancien);

        int i =0;
        crimines* c;
        detective* d;
        journaliste* j;
        //on récupére le type de la personne
        int element = g->carte[yancien][xancien];
        switch(element){
            case CRIMINEL:
                c = malloc(sizeof(criminels));
                while(tabCrim[i]->posX != xancien && tabCrim[i]->posY != yancien){
                    i++;
                }
                c = tabCrim[i];
            break;
            case DETECTIVE:
                d = malloc(sizeof(detective));
                while(tabD[i]->posX != xancien && tabD[i]->posY != yancien){
                    i++;
                }
                d = tabD[i];
            break;
            case JOURNALISTE:
                j = malloc(sizeof(journaliste));
                while(tabJournaliste[i]->posX != xancien && tabJournaliste[i]->posY != yancien){
                    i++;
                }
                j = tabJournaliste[i];
        }
...
}

同期の問題だと思いますが、どこにあるのかわかりません...

ps: 私の英語でごめんなさい :)

4

1 に答える 1

0

すべてのスレッドに同じarg配列を使用します。したがって、すべてのスレッドが単一の座標セットを共有します。これらの座標がゼロになるコード行を正確に指摘することはまだできませんが、何らかの再初期化が原因である可能性がありposYますposX。そのためのコードがないとわかりにくい。

一方、mallocそのメモリで何もせず、最終的にポインタを上書きすることさえあり、メモリリークが発生するため、呼び出しはかなり無意味に見えます。おそらく、C には配列の代入演算子がないという事実を見逃しているでしょう。a = bif ais 型int*bis 型int*orを書くことができますint[]が、これはすべての要素をコピーするのではなく、配列のアドレスをb変数 に格納するだけですamemcpyコピーの作成に使用します。

于 2013-04-24T21:07:53.920 に答える