pthread и личные данные - PullRequest
1 голос
/ 16 апреля 2011

Как я могу использовать pthreads в этой ситуации? Код получает запросы от stdin и возвращает результаты на основе некоторых правил. Но когда я создаю поток, значение id и url разделяют все потоки. Пример:

void * filter(void * data){
        int id;
        char url[1024];
        sscanf((char *) data, "%d %1024s", &id, url);
        sleep(id);
        printf("%s\n", url);
}

while(fgets(line, BUFFER, stdin)!=NULL)
   pthread_create(&thread, NULL, &filter, (void *) line);

--- Получено от стандартного ввода

1 один 2 два 3 три 4 четыре 5 пять

--- Выход

один три четыре 5 пять

- Но результаты должны быть

один два три четыре пять

Есть способ решить это? Спасибо!

Ответы [ 2 ]

2 голосов
/ 16 апреля 2011

При наличии всех потоков передается указатель на одни и те же данные, и fgets будет перезаписывать эти данные при каждом вызове. Таким образом, ваш вывод будет немного случайным и, возможно, поврежденным.

Вы можете передать копию прочитанной строки каждому потоку, и каждый поток освободит ее (например).

while (fgets(...))
  pthread_create(..., (void*)strdup(line));

В процедуре потока вы должны проверить, что переданные данные не равны нулю (это может произойти, если strdup не удалось выделить достаточно памяти для копии), и добавить:

free(data);

как только вы закончите с ним работать.

Наличие отдельного (статического) буфера для каждого потока тоже будет работать, но вам нужно будет заранее знать, сколько вы собираетесь запустить (или выполнить некоторые динамические перераспределения или что-то в этом роде).

1 голос
/ 16 апреля 2011

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

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