pthread_create не выполняется должным образом

0

Я изучаю многопоточные программы и ожидаю, что следующий фрагмент кода будет бесконечным циклом печати " foo" вместо этого ничего не произойдет

Ожидания:

foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo

Реальность:

Как будто нить даже не создается, что я делаю неправильно??? Как создать поток, который будет выполнять любую функцию, назначенную ему

Исходный код

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

#include <stdio.h>

#include <string.h>
#include <iostream>

void* print(void*);

struct threadInfo
{

    int threadID;
    int threadNo;

};

int main()
{
    pthread_t thread[3];
    bool cont = false;
    int i = 1;
    int max = 3;

    while ( cont == false )
    {
        if ( i <= max )
        {
            threadInfo t_info;
            t_info.threadID = i ;
            t_info.threadNo = i ;
            pthread_create(&thread[i-1],NULL,print,(void*)&t_info);

            i++;
        }
    }   





}

void* print(void* arg)
{
  std::cout << "Foo" ; 
  pthread_exit(NULL);
}

Следующий фрагмент кода компилируется в командной строке Ubuntu со следующей командой

g++ test.cpp -o test -lpthread
  • 0
    проверить возвращаемое значение phread_create, это плохая привычка не проверять его
  • 0
    Я предполагаю, что ваши потоки не сбрасывают свой вывод ... Но даже в этом случае вы получите только FooFooFoo, то есть один Foo на поток
Теги:
multithreading
debugging
posix

5 ответов

2

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

Время while ( cont == false ) не требуется.

  • 0
    Основной поток действительно выходит? Разве это не в бесконечном цикле?
  • 0
    @erenon это бесконечный цикл, я не вижу, как основной поток выходит перед вспомогательным потоком
1

Мой о, мой... С чего начать?

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

Ваша основная программа тратит процессорный цикл на флаг, который никогда не будет изменен. Попытка синхронизировать потоки с флагами очень плоха, несмотря на глупые новые расширения С++ 11, которые делают атомарные переменные альфа-и омегой программирования потоков.
Вы должны использовать какую-то синхронизацию, чтобы ждать окончания потоков. Самый обычный механизм - pthread_join.

Передача одного и того же экземпляра параметров каждому экземпляру вашего потока создает идеальное состояние гонки. У вас нет гарантии, что поток будет читать параметры в вашем предполагаемом порядке (т.е. до того, как основной цикл изменит их, чтобы подготовиться к запуску следующего потока). Вы должны передать каждому потоку свой собственный частный экземпляр t_info (или настроить какой-то механизм синхронизации по этой структуре).

Даже после устранения всех этих проблем вы должны ожидать только 3 "Foo", так как каждый поток выходит после одной печати.

И поскольку вы не сериализуете доступ к cout (т. cout Вы не защищаете их каким-то синхронным объектом, например мьютексом), возможно, что ваши различные потоки будут беспорядочно перемешаны (т.е. вы могли видеть что-то вроде "FoFFooooo").

  • 0
    почему он не создает новые темы после выхода из каждого потока?
  • 0
    Ваш тест if ( i <= max ) предотвращает создание более 3-х потоков.
Показать ещё 5 комментариев
1

Там ничего не напечатано, потому что выходные буферы не сбрасываются.

В функции print выполните, например,

std::cout << "Foo" << std::flush;
  • 0
    Почему я должен очистить буфер вывода? Почему вывод foo останавливается через 3 раза, должен ли он быть бесконечным?
  • 0
    @Computernerd Потому что это не делается автоматически. Если буфер не очищен, на самом деле ничего не печатается, оно просто сохраняется в буфере памяти.
Показать ещё 2 комментария
0

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

Чтобы исправить это, сделайте основной цикл соединения join loop (pthread_join() для всех созданных нитей) для всех остальных потоков до окончания или завершите основной поток, используя pthread_exit().


Также передавая адрес того же экземпляра struct threadInfo каждый протектор (то есть: (void*)&t_info) скорее всего не то, что вы хотите.

0

В pthreads нет ничего плохого. Если вы хотите обеспечить последовательность на выходе, вам необходимо приложить строку распечатки с помощью блокировки и флеша, чтобы вы обеспечили это,

1. A thread only finishes once the message has actually been printed out
2. Threads wait for each other so that no two threads write to the output at the same time

Ещё вопросы

Сообщество Overcoder
Наверх
Меню