Темы бассейна в pthread C - PullRequest
       28

Темы бассейна в pthread C

0 голосов
/ 21 февраля 2019

В моей работе с Advance OS мне нужно прочитать данные из файла и назначить их потокам для дальнейшей обработки.

Это мой код для чтения данных из файла и передачи его в функцию потока

int main() {
FILE *fp = fopen(fileName, "r");
char str_pass[80][MAX_CHAR];

if (fp == NULL){
    printf("Could not open file");
    return 1;
}
int i=0;
pthread_t thread[THREADS];
int rc;

for(int th=1; th<=THREADS; th++)
{
if(fgets(str_pass[i], MAX_CHAR, fp) != NULL){
    //printf("Hello, Thread %d\n",i);

    rc = pthread_create(&thread[i], NULL, create_thread, (void*)str_pass[i]);
    pthread_join(thread[i],NULL);

    if(rc)
    {
        printf("ERROR; return code from pthread_create() is %d\n",rc);
        exit(-1);
    }
    pthread_join(thread[i],NULL);
    i++;
    }
else{
    printf("End of File");
    exit(0);
}
}
pthread_exit(NULL);
fclose(fp);
return 0;
}

и вот мой код потока;

void * create_thread(void *hash_string)
{

    gen_combinations(hash_string);

    //sleep(1);
    pthread_exit(NULL);
    return NULL;
}

Этот код работает нормально и создает потоки столько, сколько я определяю значение в переменной THREADS, до тех пор, пока он не найдетлюбая запись в файле.Но теперь я должен сделать это с помощью концепции пула потоков.Потому что я не могу создать столько потоков, сколько данных в файле.

Поэтому мне нужно реализовать многопоточность с использованием пула потоков.Я сделал некоторые поиски по нему, но не получил никакого разрешения на это.И теперь я полностью застрял здесь и не понимаю, с чего начать и как выполнять эту работу ???

Любая помощь будет признательна.

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019
rc = pthread_create(&thread[i], NULL, create_thread, (void*)str_pass[i]);
pthread_join(thread[i],NULL);

if(rc)
{
    printf("ERROR; return code from pthread_create() is %d\n",rc);
    exit(-1);
}
pthread_join(thread[i],NULL);

Здесь две основные ошибки:

  1. Вы вызываете pthread_join сразу после создания цепочки.Это означает, что вы ждете завершения потока.Какой смысл создавать поток?

  2. Как только pthread_join вернется, поток больше не будет существовать и его идентификатор будет недействительным.Тем не менее, вы снова набираете pthread_join и передаете ему то, что раньше было удостоверением личности, но теперь является мусоромПоследствия этого совершенно непредсказуемы.

0 голосов
/ 21 февраля 2019

В вашем примере у вас есть только один активный поток за один раз.Вы запускаете его и ждете, пока он не закончится, прежде чем читать следующую строку из файла.Это вызвано pthread_join, который следует за созданием потока.Вместо этого вам нужно переместить оператор join за пределы цикла, чтобы объединить все созданные вами потоки.

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

Схематично что-то вроде следующего:

counter = 0;

while {
   lock counter;
   while (counter > 8)
      wait_on_conditional_variable
   counter ++;
   unlock counter;
   run thread;
}
join all remaining threads.

в потоке

    do work;
    lock counter;
    counter --;
    signal cond var;
    unlock counter;
    return;

Для пула вам потребуется запустить несколько потоков.Каждый поток имеет цикл, в котором он ожидает, что какая-то работа будет доступна.Скорее всего, получит его с пятерки.Для проверки требуется условная переменная.

thread
    do {
        lock fifo;
        while (fifo.size == 0) 
           wait on conditional variable.
        read job from fifo;
        unlock fifo;
        do work;

    } while (!exiting);

во время чтения файла необходимо выполнить следующее:

    while ... {
         lock fifo;
         push line into fifo;
         signal var;
         unlock fifo;
    }
    set-exit-condition;
    join the pools.

Надеюсь, это поможет.Но есть несколько способов и оптимизаций, которые вы могли бы сделать там.

0 голосов
/ 21 февраля 2019

Посмотрите на «проблему производителя / потребителя», если вы еще не знакомы с ней, в частности, варианты с несколькими потребителями.Ваш основной поток играет роль производителя, считывая данные и параметры из входного файла и упаковывая их в аккуратные единицы работы - это производимые виджеты.Рабочие потоки играют роль потребителей, принимая единицы работы и как бы «потребляя» их, фактически выполняя описанную работу.Это пул потоков.

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

...