首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSTask:为什么程序在从NSPipe读取时阻塞?

NSTask:为什么程序在从NSPipe读取时阻塞?
EN

Stack Overflow用户
提问于 2013-09-16 23:19:51
回答 1查看 494关注 0票数 0

我使用NSTask运行shell命令并通过NSPipe输出数据。首先,我使用下面的方法读取输出数据,这是没有任何问题的。

代码语言:javascript
复制
- (void)outputAvailable:(NSNotification *)aNotification {
  NSString *newOutput;
  NSMutableData *allData = [[NSMutableData alloc] init];
  NSData *taskData = nil;        
  if((taskData = [readHandle availableData]) && [taskData length])
    newOutput = [[NSString alloc] initWithData:allData encoding:NSASCIIStringEncoding];
  NSLog(@"%@", newOutput);
  [readHandle readInBackgroundAndNotify];    
}

该方法的问题是它只输出4096字节的数据。所以我使用while循环来获取更多的数据,修改方法如下:

代码语言:javascript
复制
- (void)outputAvailable:(NSNotification *)aNotification {
  NSString *newOutput;
  NSMutableData *allData; //Added.
  NSData *taskData = nil;
  while ((taskData = [readHandle availableData]) && [taskData length]) {
    [allData appendData:taskData];
  }    
  newOutput = [[NSString alloc] initWithData:allData encoding:NSASCIIStringEncoding];
  NSLog(@"%@", newOutput);
  [readHandle readInBackgroundAndNotify];
}

然后问题出现了:程序在while循环中阻塞,并且不能执行以下语句。我确保allData是我想要的,但是在添加了最后一个数据块之后,它被阻塞了。你能给我一些解决方案吗?谢谢。

EN

回答 1

Stack Overflow用户

发布于 2013-09-16 23:45:59

您的while()循环有效地阻止了进一步的通知,导致整个程序阻塞,等待某些东西刷新缓冲区。

您应该对每个通知执行readInBackgroundAndNotify,然后提取availableBytes,将其附加到您的NSMutableData (它可能保存在一个实例变量中)。在处理通知时,不要尝试等待更多数据或执行任何类型的while循环。当有更多数据可用时,系统会通知您。

也就是说,系统向您推送数据,您不会从系统中拉出数据。

啊..。好的。您仍然应该仅在有数据可用时才提取数据。您的while()循环就是这样做的。咖啡不够多。是我的错。

最后一个块很可能是因为您的外部进程没有关闭管道;没有接收到EOF,因此程序永远在等待更多从未到达的数据。

以下任一项:

当您接收到足够的数据时,请确保后台任务退出

  • 检测并终止process

如果您正在执行某种类型的转换程序(比如tr),将数据写入流程的标准输入,那么您可能需要关闭标准输入管道。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18831607

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档