2016-05-08 6 views
2

Я создавал программу для некоторых математических вычислений для некоторых номеров для школьного проекта. Скажем, у меня есть 10 потоков, но 42 элемента для обработки, я хочу, чтобы они обрабатывали все элементы равномерно и занимали ровное количество заданий. Я использую POSIX pthread library, я знаю, что это связано с мьютексом, но я не совсем уверен.Разделение между потоками? (pthread)

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

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

int numbers = { 1, 78, 19, 49, 14, 1, 14. 19, 57, 15, 95, 19, 591, 591 }; 

void* method() { 
    for(size_t i = 0; i < 14; i++) { 
    printf("%d\n", (numbers[i] * 2)); 
    } 
} 

int main(int argc, char const *argv[]) { 
    pthread_t th[10]; 
    for (size_t i = 0; i < 10; i++) { 
    pthread_create(&th[i], NULL, method, NULL); 
    } 
    return 0; 
} 
+0

Это также может зависеть от типа процесса и _items_, который необходимо обработать. В любом случае, обязательно создайте и передайте указатели на элементы в качестве аргументов потока - аргумент # 4 на 'pthread_create()'. – user3078414

ответ

1

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

Идея:

/* this structure will wrap all thread's data */ 
struct work 
{ 
    size_t start, end; 
    pthread_t  tid; 
}; 

void* method(void*); 
#define IDX_N 42 /* in this example */ 
int main(int argc, char const *argv[]) 
{ 
    struct work w[10]; 
    size_t idx_start, idx_end, idx_n = IDX_N/10; 
    idx_start = 0; 
    idx_end = idx_start + idx_n; 
    for (size_t i = 0; i < 10; i++) 
    { 
    w[i].start = idx_start; /* starting index */ 
    w[i].end = idx_end; /* ending index */ 
    /* pass the information about starting and ending point for each 
    * thread by pointing it's argument to appropriate work struct */ 
    pthread_create(&w[i], NULL, method, (void*)&work[i]); 
    idx_start = idx_end; 
    idx_end = (idx_end + idx_n < IDX_N ? idx_end + idx_n : IDX_N); 
    } 
    return 0; 
} 
void* 
method(void* arg) 
{ 
    struct work *w = (struct work* arg); 
    /* now each thread can learn where it should start and stop 
    * by examining indices that were passed to it in argument */ 
    for(size_t i = w->start; i < w->end; i++) 
    printf("%d\n", (numbers[i] * 2)); 
    return NULL; 
} 

Для немного более сложного примера, вы можете проверить this и this.

+0

А как насчет получения этих индексов? : S – JustLloyd

+0

Вы можете сделать это вручную или написать некоторую логику разбиения. – 4pie0

+0

@JustLloyd добавил пример логики – 4pie0

1

Если вы знаете заранее (то есть, до начала резьбы), сколько элементов вам нужно обрабатывать, вам просто нужно разделить их между нитями. Например, скажите первому потоку обрабатывать пункты 0-9, следующий за процессом 10-19 или что-то еще.

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