2015-02-18 4 views
1

Как бы вы это сделали в c с двоичным сокращением и барьером, реализованным с использованием двоичных семафоров? Это код, который у меня есть до сих пор. У него нет барьера, и я смущен тем, как его создать. Мне нужны блокировки для мьютексов?Найти max в массиве с помощью потоков?

# include <stdio.h> 
# include <pthread.h> 
# define arrSize 10 

struct StructMax 
{ 
    int iMax; 
}; 

int arr[arrSize]; 

void *thread_search_max(void *); 

int main() 
{ 
    pthread_t tid; 
    struct StructMax *st_main,*st_th; 
    int FinalMax; 

    st_main=(struct StructMax*)malloc(sizeof(struct StructMax)); 

    int iCount; 
    for(iCount=0;iCount<arrSize;iCount++) 
    { 
     printf("Enter Value of arr[%d] :",iCount); 
     scanf("%d",&arr[iCount]); 
    }   
    pthread_create(&tid,NULL,thread_search_max,NULL); 

    st_main->iMax=arr[0]; 

    for(iCount=1;iCount<arrSize/2;iCount++) 
    { 
     if(arr[iCount] > st_main->iMax) 
     { 
      st_main->iMax=arr[iCount]; 
     } 
    }  

    pthread_join(tid,(void**)&st_th);  

    if(st_main->iMax >= st_th->iMax) 
    { 
     FinalMax=st_main->iMax; 
    }  
    else 
    { 
     FinalMax=st_th->iMax; 
    } 


    printf("Final Max : %d \n",FinalMax); 
    return 0; 
} 


void *thread_search_max(void *para) 
{ 
    struct StructMax *st; 
    st=(struct StructMax*)malloc(sizeof(struct StructMax)); 

    int iCount; 
    st->iMax=arr[arrSize/2]; 


    for(iCount=arrSize/2 + 1;iCount<arrSize;iCount++) 
    { 
     if(arr[iCount] > st->iMax) 
     { 
      st->iMax=arr[iCount]; 
     } 
    }  

    pthread_exit((void*)st);   
} 
+0

[Не бросайте возвращаемое значение 'malloc()' in C] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). Напишите свои распределения как: 'st_main = malloc (sizeof * st_main);'. Гораздо короче, бессмысленными бросками и немного более безопасными. – unwind

+0

Как и все остальные, вы бросаете 'malloc()', [который не нужен] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc), но игнорируйте его возвращаемое значение, что является плохой практикой. Кроме того, используйте мьютекс и не используйте глобальную переменную, передайте массив функции потока через последний аргумент в 'pthread_create'. И помните, что каждый 'malloc()' должен быть сопоставлен 'free()' где-то. –

+0

Семафор? Барьеры? Я бы избегал их поисков максимума в массиве, они бы повредили производительность, чтобы вернуть вас к прямому параллельному исполнению. Если вы делаете это для производительности, я бы подумал использовать _atomics_ (с очень тщательной реализацией) или даже (если ваша архитектура позволяет вам это _trick_) с помощью _volatile_. –

ответ

1

Вы не включили stdlib.h: что является основной проблемой, но вы должны также рассмотреть некоторые другие незначительные исправления, которые сделают ваш код надежным.

Проблема с отсутствием stdlib.h заключается в том, что компилятор предполагает, что malloc() возвращает int, поэтому вы можете видеть, что это вызовет проблемы.

Если вы включите предупреждения компилятора, вы можете предотвратить такие вещи, я иногда забываю некоторые заголовки, но я не слишком далеко, потому что компилятор мне напоминает.

Предполагая, что вы работаете с gcc затем

gcc -Wall -Werror -o output $sourceFiles -pthread 

предотвратит компиляцию в этом случае.

Это улучшенная версия вашей программы, с заголовком stdlib.h включено

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

#define arrSize 10 

struct StructMax 
{ 
    int iMax; 
}; 

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 

void *thread_search_max(void *); 

int main() 
{ 
    pthread_t   tid; 
    struct StructMax *st_main; 
    struct StructMax *st_th; 
    int    FinalMax; 
    int    arr[arrSize]; 

    st_main = malloc(sizeof(struct StructMax)); 
    if (st_main == NULL) 
     return -1; 
    int iCount; 
    for (iCount = 0 ; iCount < arrSize ; iCount++) 
    { 
     printf("Enter Value of arr[%d] :",iCount); 
     scanf("%d",&arr[iCount]); 
    } 
    pthread_create(&tid, NULL, thread_search_max, arr); 

    /* lock the mutex, in this secction we access 'arr' */ 
    pthread_mutex_lock(&mutex); 
    st_main->iMax = arr[0]; 
    pthread_mutex_unlock(&mutex); 

    for (iCount = 1 ; iCount < arrSize/2 ; iCount++) 
    { 
     /* lock the mutex, in this secction we access 'arr' */ 
     pthread_mutex_lock(&mutex); 
     if (arr[iCount] > st_main->iMax) 
     { 
      st_main->iMax = arr[iCount]; 
     } 
     pthread_mutex_unlock(&mutex); 
    } 
    pthread_join(tid, (void **)&st_th); 

    if (st_main->iMax >= st_th->iMax) 
    { 
     FinalMax = st_main->iMax; 
    } 
    else 
    { 
     FinalMax = st_th->iMax; 
    } 
    printf("Final Max : %d \n", FinalMax); 
    free(st_th); 
    free(st_main); 
    return 0; 
} 

void *thread_search_max(void *para) 
{ 
    struct StructMax *st; 
    int    iCount; 
    int    *arr; 

    arr = para; 
    if (arr == NULL) 
     return NULL; 
    st = malloc(sizeof(struct StructMax)); 
    if (st == NULL) 
     return NULL; 
    /* lock the mutex, in this secction we access 'arr' */ 
    pthread_mutex_lock(&mutex); 
    st->iMax = arr[arrSize/2]; 
    pthread_mutex_unlock(&mutex); 
    for (iCount = arrSize/2 + 1 ; iCount < arrSize ; iCount++) 
    { 
     /* lock the mutex, in this secction we access 'arr' */ 
     pthread_mutex_lock(&mutex); 
     if (arr[iCount] > st->iMax) 
     { 
      st->iMax = arr[iCount]; 
     } 
     pthread_mutex_unlock(&mutex); 
    } 
    pthread_exit((void *)st); 
} 

см использование в mutex, предотвращает два потока от доступа к значению одновременно. И как глобальные переменные не нужны, кроме того, они представляют собой очень плохую идею при многопоточности.

+0

как бы вы это сделали, если бы вам пришлось начинать с кучей нитей, содержащих по два номера, и им нужно было создать решение оттуда? Предположим, что размер массива равен 2, ради моего здравого смысла и вашего. – Jf2k

0

Добавляя к вышеуказанной оптимизации, pthread должен быть создан с attrributes, указывающим, что он является совместимым (чтобы гарантировать, что pthread_join() будет блокироваться до тех пор, пока указанный поток не будет выполнен). Вы можете сделать это, объявив «attr» типа pthread_attr_t. Пример кодировки выглядит следующим образом.

pthread_attr_t attr; 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
pthread_t tid; 

pthread_create(&tid, &attr, function, args); 
//.... 
pthread_attr_destroy(&attr); 

pthread_join(&tid, (void **)status); 

pthread_attr_destroy() не вызывается до pthread_join(), потому что атр больше не требуется, как только pthread_create() вызывается с соответствующими аргументами.

 Смежные вопросы

  • Нет связанных вопросов^_^