2014-04-23 254 views
0

我正在从stdin逐行读取输入。我正在将每行发送到一个线程函数。但是我只能看到第一个输入的输出。我怎样才能看到每个输入的输出? 下面是代码多线程无法正常工作

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <string> 
#include <string.h> 
#include <iostream> 
#include <unistd.h> 

using namespace std; 

pthread_mutex_t lock; 
void *print_message_function(void *ptr); 

main() 
{ 
    pthread_t mythread[10]; 
    const char *arrays[10]; 
    int irets[10]; 

    string line; 
    int k = 0; 

    while(getline(cin,line)) 
    { 

     if(!line.empty()) 
     { 
      arrays[k] = line.c_str(); 

      irets[k] = pthread_create(&mythread[k], NULL, print_message_function, (void*) arrays[k]); 
      usleep(100); 
      k++; 
     } 
    } 

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


    pthread_mutex_destroy(&lock); 


    exit(0); 
} 

void *print_message_function(void *ptr) 
{  

    pthread_mutex_lock(&lock); 

    char *message; 
    message = (char *) ptr; 

    printf("first %s \n", message); 
    sleep(1); 
    printf("second %s \n", message); 
    pthread_mutex_unlock(&lock); 
} 

这里的输出我得到:

first hello1 
second 
first 
second 
first 
second 
first 
second 
first 
second 
first 
second 
first 
second 
first 
second 
first 
second 
first 
second 

输入是:

hello1 
hello2 
hello3 
hello4 
hello5 
hello6 
hello7 
hello8 
hello9 
hello10 

我想:

first hello1 
second hello1 
first hello2 
second hello2 
first hello3 
second hello3 
first hello4 
second hello4 
first hello5 
second hello5 
first hello6 
second hello6 
first hello7 
second hello7 
first hello8 
second hello8 
first hello9 
second hello9 
first hello10 
second hello10 
+0

你觉得会发生什么事line'的'值与通过装载机循环每次迭代你怎么想它的影响范围内'保存的数据? line的内部缓冲区(你知道,每次迭代都是圣人吗?)在启动线程之前,在你的指针数组中打印地址(所有这些),你可能会发现它。 – WhozCraig

+0

如果可能,我强烈建议使用C++ 11中的线程API。 – Jarod42

回答

1

变化const char *arrays[10];string arrays[10];
arrays[k] = line.c_str();arrays[k] = line;
(void*) arrays[k](void*)arrays[k].c_str()

问题是,一旦line更改为下一个值之前的arrays[k]指向一段毫无意义的内存。您必须保存line的值才能使线程访问它。

2

arrays[k] = line.c_str(); 这不是做你认为它...而且由于这是你给你的print_message功能...

+0

是的,你必须memcopy数据或者创建一个std :: strings数组。因为当修改'input''input.c_str()'确实也改变了。 – Theolodis

1

std::string::c_str()的结果只有guaranteedly可作为std::string不会改变,不会被破坏(当你做你无效以前c_str()的结果,一个新的函数getline。如果你不能保持const char*比更多的时间这一点,你将需要采取一个副本我爱:

arrays[k] = malloc(line.size()+1); //Plus 1 because of the \0 on the end of the string 
memcpy(arrays[k],line.c_str(),line.size()+1); 
+0

当我们有更好的类似C++的方式时,为什么要回到类C方法呢? – Dialecticus

+0

@Dialecticus关于这个问题的教学目的。了解什么是错误的以避免将来的错误是非常有价值的。我当然更喜欢C++方法。 –