我实际上不确定如何为我的问题找到最佳标题,但请让我解释一下......
在我的应用程序中,我必须通过TCP实现问题/答案类型的协议,客户端发送问题,等待一个或多个答案,然后才发送后续问题。
问题只是正常发送,而收到的答案会触发回调-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
这里是主循环:
- (void) doQandA {
BOOL ok;
int runMessages[7] = {0,1,2,3,2,0,3};
int msgIndex = 0;
int msgNumber = runMessages[msgIndex];
waitingForResponse = FALSE;
while (msgIndex < 6) {
if (!waitingForResponse) {
ok = [self sendQuestionMsg: msgNumber];
msgIndex++;
msgNumber = runMessages[msgIndex];
}
}
}
发送实际上是......
- (void) sendQuestionMsg: (int) msgNo {
//sendMsg over TCP
[self sendQuestionNo: msgNo];
waitingForResponse = TRUE;
}
并收到答案......
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
[self handleAnswer: data];
}
-(void) handleAnswer: (NSData*) data {
//do stuff
waitingForResponse = FALSE;
}
这实际上是这样做的正确方法吗?我担心我的主要doQandA循环太CPU密集了。难道没有更好的方法等待答案吗?
我希望我能澄清一下我的问题...... 非常感谢
答案 0 :(得分:1)
答案是否定的,这不是正确的做法。
您实施的内容称为 busy-wait 循环。 doQandA()
中的循环一直在旋转,不断执行 - 你担心这一点绝对是正确的。
正确的做法是在该循环中进行阻塞调用 - 在事件发生之前暂停进程的调用。在这种情况下,您正在等待的事件是要到达的网络数据包。
执行此操作的常用方法是阻止类似read()
,recv()
,poll()
或select()
的系统调用,这将在网络数据包到达时返回。然后,您将直接从主循环调度didReadData()
函数。