Можно ли использовать pthreads без pthread_join ()? - PullRequest
3 голосов
/ 22 июня 2011

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

Вотсценарий ...

У меня есть бесконечный цикл в моем основном методе (сервере), порождающем потоки для обработки данных всякий раз, когда он получает пакет от любого клиента.Проблема в том, что я не могу заставить потоки выполняться одновременно.Они отказываются начинать выполнение до вызова pthread_join () из основного метода, который полностью убивает всю цель использования потоков в первую очередь (серверу нужно ОСТАНОВИТЬ поток выполнения и ждать, пока поток завершит обработку своих данных, прежде чем получитьбольше пакетов! смешно.)

Так есть ли способ использовать pthreads и действительно ли они многопоточные?Или мне лучше вообще не использовать потоки и сохранять дополнительные ресурсы, останавливая выполнение на моем сервере для вызова функции для обработки данных?

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

Это расстраивает ....

ниже приведен пример кода, который я сделал:

// gcc threads.c -lpthread
#include <stdio.h>
#include <pthread.h>

struct point{
    int x, y;
};

static void *print_point(void *point_p);

int main() {
    pthread_t tid;
    struct point pt = {3, 5};
    printf("enter main\n");
    pthread_create(&tid, NULL, print_point, &pt);
    while(1){continue;}
    return 0;
}

static void *print_point(void *point_p) {
    struct point arg = * (struct point *) point_p;
    printf("Point: (%d, %d)\n", arg.x, arg.y);
    return NULL;
}

когда я запускаю и компилирую это (да, я компилирую с -Переключатель lpthread), он печатает «enter main» и не выполняет поток ... Я даже позволил ему какое-то время работать (встал, пошел в ванную, съел немного еды), и все еще ничего.

Таким образом, поскольку основной метод порождает поток, а затем циклически повторяется, поток в конечном итоге должен выполняться ... верно?Из того, что я могу сказать из своих тестов, основной метод никогда не отдает выполнение потоку, который он породил.Единственный способ, которым я могу заставить его отказаться от него, вызвав join (но это лишает смысла иметь потоки, так как main будет ждать до завершения потока).

Ответы [ 2 ]

5 голосов
/ 22 июня 2011

Вы никогда не дадите потоку возможность выполнить с этим while(1){continue;}.Здесь произойдет одно из двух:

  1. Вы скомпилировали с достаточно высокой оптимизацией, что компилятор делает весь этот цикл исчезающим.Поток никогда не получает возможности выполнить, потому что main запускает поток и затем сразу возвращает ноль.
  2. Компилятор не оптимизирует цикл.С этим занятым циклом вы снова не даете механизму потока ускользнуть.

Добавьте вызов sleep (0); в тело этого занятого цикла.

2 голосов
/ 22 июня 2011

На самом деле ваш код работает нормально для меня, но я думаю, что ваша проблема в том, что основной поток находится в этом цикле while(), перегружая все использование процессора, поэтому у второго потока никогда не будет шанса.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * На то, что pthread_join заставляет его работать. Это что-то вроде красной сельди: он просто останавливает основной поток, чтобы другие потоки получили шанс.

Очевидно, что правильным решением для этого является заставить основной поток спатьправильно, когда это не имеет ничего общего.В качестве тестового кода попробуйте ввести sleep(1) в цикл while.

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