C ++ запутался в потоках - PullRequest
       30

C ++ запутался в потоках

1 голос
/ 10 февраля 2010

В основном это то, что у меня есть:

Server::
Server (int port) {
    cout << "Initializing server.\n";

    (...)       

    pthread_t newthread;
    pthread_create(&newthread, NULL, &Server::_startListening, NULL);

    cout << "Exit\n";
    pthread_exit(NULL); // <-- Question
}

void* Server::_startListening (void* param) {
cout << "Start listening for clients ...\n";
return 0;
}

Вопрос: Если я не поставлю pthread_exit (NULL); в коде он будет работать, когда я скомпилирую его в Linux (Ubuntu), но не будет работать в Mac OSX 10.6.2. Когда я компилирую и запускаю его в linux, он говорит «Инициализация сервера», «Начать прослушивание клиентов», «Выход», а в Mac OSX - «Инициализация для сервера», «Выход», «Начать прослушивание клиентов».

Кажется, проблема возникает вокруг pthread_exit, если я помещу его выше cout << Выход. Это сообщение никогда не будет отображаться (как это ни странно). </p>

Я что-то не так делаю?

Ответы [ 6 ]

7 голосов
/ 10 февраля 2010

вы, вероятно, намереваетесь использовать pthread_join вместо выхода.

3 голосов
/ 10 февраля 2010

Проблема, кажется, возникает вокруг pthread_exit, если я помещу его выше cout << Выход. Это сообщение никогда не будет отображаться (как это ни странно). </p>

Не странно. Когда вы вызываете pthread_exit, текущий поток останавливается. Так как только в этом потоке вы будете отображать «выход», после того, как этот поток пропадет, у него не останется ничего для его печати. ​​

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

1 голос
/ 10 февраля 2010

Порядок вашего вывода не определен. Вот что значит параллелизм! Два других ответа верны: pthread_exit до того, как ваш вывод убьет основной поток, и вы, вероятно, намереваетесь присоединиться до того, как произойдет основной выход.

0 голосов
/ 10 февраля 2010

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

0 голосов
/ 10 февраля 2010

pthread_exit должен вызываться из потока, который вы хотите остановить. Вызов его из потока main() прервет основной поток, и ваша программа будет работать до тех пор, пока не завершатся потоки слушателя.

Рекомендую прочитать справочные страницы на pthread_exit и pthread_join.

0 голосов
/ 10 февраля 2010

Потоки (планирование и т. Д.) Зависят от ОС. Похоже, что в Linux ваша ОС переключает контекст на новый поток, прежде чем продолжить работу в основном потоке, в то время как в Mac OS она продолжит выполнение текущего потока перед переключением контекста. Поскольку это зависит от ОС, если вы не выполняете какую-либо синхронизацию, нет надежного способа определить, какая строка из двух потоков будет выполняться первой, и даже ваш протестированный linux будет переключать контексты, результаты ненадежны.

pthread_exit, как упоминалось выше, выходит из активного текущего потока (то есть: main ()), а не из любых других потоков (_startListning). Возможно, вы ищете присоединение (pthread_join) к другому потоку, а не выход из текущего.

...