Поток внутри другого потока в цикле while

0

Я новичок в C++, и сейчас я экспериментирую с потоками. Я пытаюсь создать поток внутри потока в цикле while. Но я не думаю, что это работает. В настоящее время мой код выглядит так:

#include <>
std::vector<pthread_t> outer_thread, inner_thread;

    void *inner_thread(void *ptr)
    {
      string data1;
      data1 = *(reinterpret_cast<string*>(ptr));
      cout << "inner thread started " << data1;

/* do something */
      cout << "inner thread stopped " << data1;

pthread_exit(NULL);
  return 0;


    }

    void *outer_thread(void *ptr )
    {
cout << "out thread started" << endl;
//cout << ptr << endl;
//cout << *(reinterpret_cast<string*>(ptr)) << endl;
string data;
data = *(reinterpret_cast<string*>(ptr));


      string str3;
while (getline(data,str3))
{
      cout << "out thread started" << endl;


pthread_t in_thread;
in_vec.push_back(str3);
                int create_thread2 = pthread_create(&in_thread, NULL, &inner_thread, reinterpret_cast<void*>(&(in_vec.at(j))));
                inner_thread.push_back(in_thread);


      if (create_thread2 != 0) 
        cout << "Error : Thread";


      j++;

      cout << "out thread ends " << j << create_thread2 << endl ;

    }
         for (int k = 0; k < j ; k++)

{
pthread_join(inner_thread.at(k),NULL) ;
}

pthread_exit(NULL);
  return 0;

}   
    int main (int argc, char *argv[])
    {
      int i = 0;
      while (getline(gin,str))
      {
 string str1;
                pthread_t out_thread;
                cout << "str1" << str1 << endl;
now_vec.push_back(str1);
int create_thread = pthread_create(&out_thread, NULL, &outer_thread, reinterpret_cast<void*>(&(now_vec.at(i))));
                outer_thread.push_back(out_thread);
                if (create_thread != 0) cout << "Error : Thread" ;

        i++;
      }

for (int k = 0 ; k < i; k ++)
{
cout << i << endl;
//cout << "third thread " << outer_thread.at(1) << endl;
cout << outer_thread.at(k) << endl;
cout << "out out out" << endl;
pthread_join(outer_thread.at(k),NULL) ;
}


    }

Я пытаюсь прочитать файл, который содержит список файлов, которые следует читать. Я хочу читать все эти файлы одновременно. Все эти файлы содержат информацию и требуют другого набора потоков для запуска другой операции. Так что это также нужно делать одновременно. Это причина, по которой у меня есть 2 набора потоков. Дайте мне знать. Если есть более быстрый и простой способ сделать это?

Кажется, дождитесь окончания внутренней нити, а затем начнется со следующей итерации. Я хочу, чтобы внутренние потоки выполнялись одновременно внутри внешней нити. Могу ли я узнать, как это сделать?

  • 0
    Включите предупреждения вашего компилятора. Вы не возвращаете значения.
  • 3
    у вас есть pthread_join внутри цикла ... вот почему ждет.
Показать ещё 9 комментариев
Теги:
multithreading
while-loop

2 ответа

3

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

Некоторые простые правила, которые следует соблюдать при работе с несколькими потоками:

  • Создание потоков является дорогостоящим, поэтому избегайте быстрого создания и уничтожения. Лучше всего создавать свои потоки один раз в начале вашего приложения и назначать им работу, поскольку работа становится доступной.
  • При выполнении вычислительной работы избегайте создания большего количества потоков, чем может одновременно выполняться на вашем процессоре. Любые дополнительные потоки вызовут избыточные переключатели контекста и замедляют ваше приложение.
  • Избегайте использования общих ресурсов как можно чаще, если структура данных должна быть разделена между потоками, попробуйте и найдите реализацию без блокировки. Если ваш общий ресурс недоступен для реализации без блокировки, используйте блокировки для его защиты, но будьте осторожны, неправильное использование блокировок может привести к блокировке вашего приложения или к ухудшению производительности вашего приложения в случае серийного исполнения (как если бы там был только один поток).

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

  1. Читайте в списке файлов для работы
  2. Разделите список на разделы (один раздел для каждого логического процессора на вашем CPU).
  3. Создайте свои рабочие потоки (по одному на каждый логический процессор), проходящие в их разделе списка файлов (не пытайтесь присоединиться к потоку в том же цикле, который его создает, это будет блокироваться до тех пор, пока поток не завершит выполнение, заставляя приложение запускаться последовательно а не параллельно, что имеет место в примере кода, который вы указали)

Рабочие потоки могут перебирать их список файлов, считывая их по одному и обрабатывая их.

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

Примитивный пример:

#include <pthread.h>
#include <vector>
#include <string>

#define NUM_THREADS 4

std::vector<std::string> work_pool[NUM_THREADS];

void *worker_thread(void *args);

int main(int argc, char *argv[])
{
    pthread_t threads[NUM_THREADS];

    // Read list of files here, distribute them evenly amongst the work_pools

    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_create(&threads[i], NULL, worker_thread, (void *)i);
    }

    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }

    return 0;
}

void *worker_thread(void *args)
{
    const int id = (int)args;
    std::vector<std::string>::iterator it;

    for (it = work_pool[id].begin(); it != work_pool[id].end(); it++) {
        // Read file and process it here
    }

    return NULL;
}
  • 0
    Я изменил сценарий на основе ваших предложений. Не уверен, что это то, что вы имели в виду, но вам нужна была обратная связь
  • 0
    Я изменил сценарий, но значение не передается правильно во всех местах. Не уверен, что проблема может быть!
Показать ещё 2 комментария
0

Не уверен, что вы пытаетесь сделать, но среди многих синтаксических ошибок, которые, как я надеюсь, проистекает из простого кода, вот что происходит:

  1. Основной поток порождает поток (1) и ждет его завершения (join)
  2. (1) thread выполняет внешний_thread и порождает другой поток (2) и ждет его завершения (join)
  3. (2) поток выполняет inner_thread и заканчивает.
  4. (2) соединяется и (1) резьба может закончить.
  5. (1) соединяется, и основной поток может перейти к следующей итерации.
  6. процесс начинается снова.

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

Обратите внимание, что бросание потоков при задании - это не способ ускорения.

Темы - это способ:

  • Лучше использовать ресурсы вашего процессора (когда у вас много ресурсов ЦП... и используется только столько потоков, сколько у вас ресурсов ЦП)
  • Упрощение организации вашего кода путем инкапсуляции запросов в виде потоков (но этот вид трюка очень плохо)
  • 0
    Как я могу начать параллельное выполнение в этом случае?
  • 0
    @ user3309525 не ждите окончания одного потока, чтобы начать следующий ...
Показать ещё 1 комментарий

Ещё вопросы

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