2016-10-03 143 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

把一個符號之前的任務:在pthread_create(&線程[I​​],NULL,&任務,(無效*)ⅰ) ; – alangab

回答

3

的第一個問題是,task應該返回void*,不void,如由pthread_create原型規定:

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

這很容易解決。

第二個問題是你不應該通過i這種方式 - 你不應該投intvoid*。通過itask一種方法是分配的內存空間小,使用它:

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*)&ipthread_create,因爲不能保證*(int*)arg將在for循環的增量之前被評估,所以你可能會得到一些奇怪的行爲在您讀取其值之前,已更改。

+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; 
} 

這樣可以避免因遇到空白和整數尺寸不同而出現的錯誤。

而且它會給寫返回類型任務

0

做出一些改變:第13行和線59 因爲任務被用作指針pthread_create功能發揮作用

int pthread_create(pthread_t * thread,const pthread_attr_t * attr, void *(start_routine)(void),void * arg);

2- int i = *((int *)arg);在管線60 3-編譯這樣的gcc Barrier.c -lpthread