【问题标题】:Thread inside another thread in a while loop [closed]在while循环中另一个线程内的线程[关闭]
【发布时间】:2014-08-03 01:37:08
【问题描述】:

我对 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 组线程的原因。 让我知道是否有更快更简单的方法来做到这一点?

似乎要等到内部线程完成,然后再开始下一次迭代。我希望内螺纹在外螺纹内同时运行。我可以知道该怎么做吗?

【问题讨论】:

  • 打开编译器警告。你没有返回值。
  • 你有pthread_join inside循环......这就是等待的原因。
  • pthread_t threads[i]; 在第一次迭代中,您没有正确分配此处 (int i = 0;)。
  • 这里有很多问题。 pthread_t threads[i]; 在第一次迭代时大小为 0,&amp;threads[i] 指向数组末尾,j 未在任何地方声明,等等。
  • ... 线程 inside 线程这一事实没有意义。一个(重)进程包含一个或多个(轻)进程(又名线程)。这些线程是从代码中的不同点创建的,但执行线程创建请求的线程和生成的线程之间没有任何关系。

标签: c++ multithreading while-loop


【解决方案1】:

你对线程操作的看法是错误的。一个线程不在另一个线程中运行。它们是同一进程中的独立执行流,它们的共存是扁平的,而不是分层的。

处理多线程时要遵循的一些简单规则:

  • 创建线程的成本很高,因此请避免快速创建和销毁它们。最好在应用程序启动时创建一次线程,并在工作可用时为其分配工作。
  • 在进行计算工作时,请避免创建多于 CPU 可以同时执行的线程。任何额外的线程都会导致过多的上下文切换并减慢您的应用程序。
  • 尽可能避免使用共享资源,如果必须在线程之间共享数据结构,请尝试找到无锁实现。如果您的共享资源在无锁实现中不可用,则使用锁来保护它,但要非常小心,锁使用不当可能会导致您的应用程序死锁或您的应用程序性能降级到串行执行情况(好像有只是一个线程)。

在您的特定情况下,如果您想通过并行处理多个文件来加速处理多个文件(并假设这些线程需要完成的唯一任务是处理这些文件),那么可能的解决方案如下:

  1. 读入要操作的文件列表
  2. 将列表分成多个部分(CPU 上的每个逻辑处理器一个部分)。
  3. 创建您的工作线程(每个逻辑处理器一个)传递文件列表的它们的部分(不要尝试在创建它的同一循环中加入线程,这将阻塞直到线程完成执行导致您的应用程序串行执行而不是并行执行,您提供的示例代码就是这种情况)

工作线程可以遍历他们的文件列表,一次读取一个文件并处理它们。

与您提出的解决方案相比,这个解决方案不会为每个文件创建一个线程。相反,它将在您的 CPU 上创建尽可能多的线程并行运行,从而避免过多的上下文切换。

上面的一个原始示例:

#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;
}

【讨论】:

  • 我根据您的建议修改了脚本。不确定这是否是您的意思,但需要有关代码的反馈
  • 我修改了脚本,但没有在所有地方正确传递值。不知道可能是什么问题!
  • 问题在于,我永远无法确定我需要多少线程。那里的 NUM_THREADS 可以在 0 到 10 或 20 之间变化。
  • 线程数不应超过 CPU 上的逻辑处理器数(针对此类问题)。如果您有 4 个内核和超线程,那么您的 CPU 可以同时运行 8 个线程。如果您创建的线程比这更多,您将减慢速度而不是加快速度。如果您有 400 个文件的列表要处理,只需向每个 work_pool 添加 100 个文件名,然后每个工作线程将一次处理一个。
【解决方案2】:

不确定您要做什么,但在我希望您的代码简单化导致的许多语法错误中,会发生以下情况:

  1. 主线程产生一个线程 (1) 并等待它完成(加入)
  2. (1) 线程执行 outer_thread 并产生另一个线程 (2) 并等待它完成(加入)
  3. (2) 线程执行 inner_thread 并完成。
  4. (2) 已加入并且 (1) 线程能够完成。
  5. (1) 被加入,主线程能够进入下一次迭代。
  6. 进程再次启动。

请注意,您没有任何并行执行,因为您的线程正在等待其他完成。

请注意,在任务中抛出线程并不是加快速度的方法。

线程是一种方式:

  • 更好地使用您的 CPU 资源(当您有多个 CPU 资源时......并且只使用与您拥有的 CPU 资源一样多的线程)
  • 通过将请求封装为线程来简化代码的组织(但这种技巧的规模非常大)

【讨论】:

  • 在这种情况下如何启动并行执行?
  • @user3309525 不要等待一个线程完成来启动下一个......
  • 我不确定如何在 while 循环之前声明线程,因为我不确定需要多少线程。
猜你喜欢
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 2016-04-11
  • 2015-06-14
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多