2016-10-03 8 views
0

私は以下のコードを持ち、コンパイルしてエラーなく実行しますが、コンパイラは私が "解決したい"という警告を表示します。私のコードザッツキャストと引数の警告

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <semaphore.h> 
#include <unistd.h> 

typedef struct s_Barrier{ 
    sem_t sEntry, sMutEx, sExit; 
    int nTaskInBarrier; 
}Barrier; 

void createTasks(pthread_t threads[]); 
void task(void *arg); 
void initBarrier(Barrier *pb, int n); 
void destroyBarrier(Barrier *pb); 
void waitInBarrier(Barrier *pb); 


Barrier barrier; 
int nTask = 5; 


int main(void) { 
    pthread_t threads[nTask]; 

    initBarrier(&barrier,nTask); 
    createTasks(threads); 
    destroyBarrier(&barrier); 

    return 0; 
} 

void createTasks(pthread_t threads[]){ 
    int i; 

    for(i = 0; i < nTask; i++){ 
     pthread_create(&threads[i], NULL, task, (void*)i); 
    } 

    for(i = 0; i < nTask; i++){ 
     pthread_join(threads[i], NULL); 
    } 
} 

void initBarrier(Barrier *pb, int n){ 
    pb->nTaskInBarrier = 0; 

    sem_init(&pb->sEntry,0,n); 
    sem_init(&pb->sExit,0,1); 
    sem_init(&pb->sMutEx,0,1); 
} 

void destroyBarrier(Barrier *pb){ 
    sem_destroy(&pb->sEntry); 
    sem_destroy(&pb->sExit); 
    sem_destroy(&pb->sMutEx); 
} 

void task(void *arg){ 
    int i = (int) arg; 
    while(1){ 
     printf("I'm thread %d\n",i); 
     waitInBarrier(&barrier); 
    } 
} 

void waitInBarrier(Barrier *pb){ 
    int x; 
    int i; 

    sem_wait(&pb->sEntry); 
    sem_wait(&pb->sMutEx); 

    x = ++pb->nTaskInBarrier; 

    sem_post(&pb->sMutEx); 

    if(x < nTask){ 
     sem_wait(&pb->sExit); 
    }else{ 
     for(i = 0; x < nTask ; i++){ 
      sem_post(&pb->sExit); 
     } 
    } 

    sem_wait(&pb->sMutEx); 

    x = --pb->nTaskInBarrier; 

    sem_post(&pb->sMutEx); 

    if(x == 0){ 
     for(i = 0; x < nTask ; i++){ 
      sem_post(&pb->sEntry); 
     } 
    } 

} 

私が使用してコンパイルし、次の警告を得る "のgcc -oバリア3.4Barrier.cは-pthread"。

3.4Barrier.c: In function ‘createTasks’: 
3.4Barrier.c:47:43: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 
    pthread_create(&threads[i], NULL, task, (void*)i); 
            ^
    3.4Barrier.c:47:37: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [-Wincompatible-pointer-types] 
    pthread_create(&threads[i], NULL, task, (void*)i); 
           ^
In file included from 3.4Barrier.c:13:0: 
/usr/include/pthread.h:233:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘void (*)(void *)’ 
extern int pthread_create (pthread_t *__restrict __newthread, 
     ^
    3.4Barrier.c: In function ‘task’: 
    3.4Barrier.c:70:10: warning: cast from pointer to integer of different size  [-Wpointer-to-int-cast] 
    int i = (int) arg; 
+0

タスクの前にアンパサンドを入れ-lpthread ; – alangab

答えて

3

最初の問題はpthread_createのプロトタイプで指定されtaskはないvoidvoid*を返すべきであることである。

void* task(void *arg) { 
    // ... 
    return NULL; 
} 

これは容易に解決されます。

第2の問題は、iにこのように渡すべきではないということです。intvoid*にキャストしないでください。 taskiを渡すための一つの方法は、メモリの小さなスペースを割り当て、それを使用することです:

for(i = 0; i < nTask; i++){ 
    int *pi = malloc(sizeof(int)); 
    if (pi == NULL) { 
     // Something wrong... 
    } 
    *pi = i; 
    pthread_create(&threads[i], NULL, task, pi); 
} 

そして:

void* task(void *arg){ 
    int i = *(int*)arg; // Cast to `int*` and then dereference. 
    free(arg); // Don't forget this! 
    while(1){ 
     printf("I'm thread %d\n",i); 
     waitInBarrier(&barrier); 
    } 
    return NULL; 
} 

は直接(void*)&iに合格しようとしないでくださいループのインクリメントより前に*(int*)argが評価されるという保証がないので、あなたは何らかの奇妙な振る舞いを得るかもしれないので、pthread_createへre iは値を読み取る前に変更されています。

+0

すべての警告を解決しました!どうもありがとう! –

0

変更この

void createTasks(pthread_t threads[]){ 
    int i; 

    for(i = 0; i < nTask; i++){ 
     pthread_create(&threads[i], NULL, task, (void*)i); 
    } 

へ:

void createTasks(pthread_t threads[]){ 
    int i; 

    for(i = 0; i < nTask; i++){ 
     int *arg = malloc(Sizeof(int)); 
     *arg = i; 
     pthread_create(&threads[i], NULL, task, (void*)arg); 
    } 

次に変更:

void task(void *arg){ 
    int i = (int) arg; 
    while(1){ 
     printf("I'm thread %d\n",i); 
     waitInBarrier(&barrier); 
    } 
} 

void *task(void *arg){ 
    int i = *((int *) arg); 
    free(arg); 
    while(1){ 
     printf("I'm thread %d\n",i); 
     waitInBarrier(&barrier); 
    } 
    return 0; 
} 

これは、voidとintのサイズが異なるという問題を解決するために発生したエラーを回避します。

また、それはいくつかの変更を加えるタスク

0

の書き込み戻り値の型を与える:タスクがpthread_create機能に

を関数へのポインタとして使用されているので、ライン13でライン59 で の1- void *task(void *arg);

int pthread_create(pthread_t * thread、const pthread_attr_t * attr、 void *(start_routine)(void)、void * arg); (&スレッド[i]は、NULL、&タスク、(ボイド*)I)のpthread_create:60 3-このGCC Barrier.cようなコンパイル行に

2- int i = *((int *)arg);

関連する問題