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