2014-06-12 82 views
0

我很新的C++和我现在正在尝试线程。 我想在while循环下的线程内创建一个线程。但我认为这似乎没有奏效。 目前我的代码看起来是这样的:在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

打开你的编译器警告。你没有返回值。 – chris

+3

你有[pthread_join](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html)*内循环...这就是为什么在等待。 – jsantander

+0

'pthread_t threads [i];'你在第一次迭代中没有正确地分配('int i = 0;')。 –

回答

0

不知道你想要做什么,但我希望来自simplying你的代码中的许多语法错误当中,这是发生了什么:

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

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

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

线程是的一种方式之一:

  • 使用的CPU资源(当你有多个CPU资源......,只使用尽可能多的线程,你有CPU资源)
  • 简化组织更好通过将请求封装为线程(但这种技巧缩放非常糟糕)
+0

如何在这种情况下启动并行执行? – user3309525

+0

@ user3309525不等待一个线程完成以开始下一个... – jsantander

+0

我不确定如何在while循环之前声明线程,因为我不确定将需要多少个线程。 – user3309525

2

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

一些简单的规则,以多线程工作时遵循:

  • 创建线程是昂贵的,所以要避免创建和销毁很快他们。最好在应用程序开始时创建一次线程,并在工作变得可用时将其分配。
  • 在做计算工作时,避免创建比在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; 
} 
+0

我根据您的建议修改了脚本。不知道这是你的意思,但需要代码的反馈 – user3309525

+0

我修改了脚本,但没有正确地传递值在所有的地方。不知道什么问题可能是! – user3309525

+0

问题在于,我永远无法确定我需要的线程数量。 NUM_THREADS可以在0到10或20之间变化。 – user3309525