线程不要刷新数据,无法从stdin获取所有数据

时间:2012-05-04 13:24:59

标签: c++ multithreading sockets

我正在创建一个套接字程序,用于将数据从一台PC传输到另一台,但是当我发送一些二进制数据进行处理时,我遇到了问题。 在这种情况下,我需要一个线程来监听数据套接字发送数据时的消息套接字。 所以我发现问题不是套接字,如果我试图将数据写入屏幕(这次没有套接字),就会出现问题。 所以我尝试使用fflush(stdout)刷新数据而没有运气。 代码以这种方式工作。

Initialize the 2 sockets.
Initialize 2 threads.
  One to get the data back through the data socket.
  The other send the data.    
And while sending all the data one pthread_join(m_thread2) in the main function, because the data can take 1 second to be processed or one hour so i keep the program alive this way.

我创建了一个较小的版本,使用两个线程来读取并发送到屏幕,然后在主屏幕中。

代码:

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

using namespace std;

const int RCVBUFSIZE=2000;
char echoString[RCVBUFSIZE];
int recvMsgSize;
static void * _sendExec(void *instance);
static void * _recvExec(void *instance);
int main(){
  pthread_t m_thread, m_thread2;
  int merror, merror2;
  merror=pthread_create(&m_thread, NULL, _sendExec, NULL);
  merror2=pthread_create(&m_thread2, NULL, _recvExec, NULL);
  pthread_join(m_thread2, NULL);
}
static void * _sendExec(void *instance){
  int size;
  for(;;){
    while((size=read(fileno(stdin), echoString, RCVBUFSIZE))>0){
       write(fileno(stdout), echoString, size);
    }
    fflush(stdin);
    fflush(stdout);
    pthread_exit(0);
  }
}
static void * _recvExec(void *instance){
  while(1){
     //recvMsgSize=msgTmp->recv(buffer, RCVBUFSIZE)
     write(fileno(stdout), "", 0);
     sleep(1);
  }
}

如果您尝试cat file.tar.gz | ./a.out | tar -zvt,您可以看到并非所有数据都显示在屏幕上,如果我放在主屏幕上,删除pthread_join就可以了,问题是我需要数据回来它可能需要时间。 就像我做cat file.tar.gz | ssh root@server "tar -zvt"一样。 问题是,我只是可以在使用recvExec收回所有数据后终止sendExec,但它只是将stdin刷回给我之后 更改了代码并删除了套接字部分,只是为了说明问题

谢谢大家

1 个答案:

答案 0 :(得分:1)

在您的示例中,tar正在等待更多输入,因为您从未提供文件结束指示。试试这个:

static void * _sendExec(void *instance){
  int size;
  for(;;){
    while((size=read(fileno(stdin), echoString, RCVBUFSIZE))>0){
       write(fileno(stdout), echoString, size);
    }
    fflush(stdin);
    fflush(stdout);
    fclose(stdout); // THIS IS THE LINE THAT FIXES THE SAMPLE PROGRAM
    pthread_exit(0);
  }
}

虽然添加fclose修复了您的示例程序,但我不一定会在您的主程序中推荐它。您的样本中仍然存在无限循环(在_recvExec中)并且永​​远不会终止。