CFWriteStreamScheduleWithRunLoop 有时有效,有时无效?

发布于 2024-10-06 20:47:57 字数 1617 浏览 0 评论 0原文

我正在进行异步套接字编程,并且我的代码在大多数情况下都可以工作,但有时却不能。要点是:我创建一个套接字对,创建读取和写入流,然后当我想写一些东西时,我将其安排在单独线程的运行循环上。像这样:

CFStreamClientContext context = {0, sc, NULL, NULL, NULL};
if (CFWriteStreamSetClient(sc.writeStream, kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, myWriteStreamCallBack, &context)) {
 CFWriteStreamScheduleWithRunLoop(sc.writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}

...其中 myWriteStreamCallback 是正确形式的静态函数...

套接字/流是这样打开的:

CFReadStreamRef readStream  = NULL;
CFWriteStreamRef writeStream = NULL; 

@try {
   // create a pair of streams to the host and open them

  CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, scomm.host, SERVER_PORT, &readStream, &writeStream);
  if (readStream == NULL)     @throw [[[CommunicationReadStreamNotCreatedException alloc] init] autorelease];
  if (writeStream == NULL)    @throw [[[CommunicationWriteStreamNotCreatedException alloc] init] autorelease];
  if (!CFReadStreamOpen(readStream))  @throw [[[CommunicationReadStreamNotOpenedException alloc] init] autorelease];
  if (!CFWriteStreamOpen(writeStream)) @throw [[[CommunicationWriteStreamNotOpenedException alloc] init] autorelease];
  ...

现在问题是:这段代码(还有更多,如果它能帮助任何人),主要是正确,因为它基本上有效。然而,有时,在程序的一开始,我可以尝试以这种方式发送一些数据,并且套接字的回调将正确地放置在运行循环中,但随后它永远不会被调用。稍后在程序中,将使用另一个套接字运行相同的代码,并且将调用回调(套接字转到相同的地址)。

我知道这很模糊,但在我发布所有代码之前,是否有人对可能导致此问题的事情有任何粗略的想法?也就是说,回调有时不会在运行循环上被调用。

哦,是的,我应该补充一点,这显然是某种类型的竞争条件 - 我可以通过在正确的位置添加日志语句来可靠地解决问题。然后,使用完全相同的代码,它有时有效,有时无效。有趣有趣。

I'm doing async socket programming, and my code works, most of the time, but sometimes it doesn't. The gist is: I create a socket pair, create read and write streams, and then when I want to write something, I schedule it on a run loop of a separate thread. Like so:

CFStreamClientContext context = {0, sc, NULL, NULL, NULL};
if (CFWriteStreamSetClient(sc.writeStream, kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, myWriteStreamCallBack, &context)) {
 CFWriteStreamScheduleWithRunLoop(sc.writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}

... where myWriteStreamCallback is a static function of the correct form...

the sockets/streams were opened like so:

CFReadStreamRef readStream  = NULL;
CFWriteStreamRef writeStream = NULL; 

@try {
   // create a pair of streams to the host and open them

  CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, scomm.host, SERVER_PORT, &readStream, &writeStream);
  if (readStream == NULL)     @throw [[[CommunicationReadStreamNotCreatedException alloc] init] autorelease];
  if (writeStream == NULL)    @throw [[[CommunicationWriteStreamNotCreatedException alloc] init] autorelease];
  if (!CFReadStreamOpen(readStream))  @throw [[[CommunicationReadStreamNotOpenedException alloc] init] autorelease];
  if (!CFWriteStreamOpen(writeStream)) @throw [[[CommunicationWriteStreamNotOpenedException alloc] init] autorelease];
  ...

Now to the problem: this code (and there's more, if it'll help anyone), is mostly correct, because it mostly works. However, sometimes, at the very beginning of the program, I can try to send some data this way, and the callback for the socket will correctly be placed on the run loop, but then it'll never get called. Later in the program, the same code will be run with another socket, and the callback will get called (sockets go to the same address).

I know this is vague, but before I get into posting all of the code, does anyone have any rough ideas about things that could potentially cause this? Callbacks sometimes not getting called on runloops, that is.

Oh yeah, I should add that this is obviously some type of race condition - I can unreliably make the problem go away by adding in logging statements at the right places. And then, it sometimes works and sometimes doesn't, with the exact same code. Fun fun.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云胡 2024-10-13 20:47:57

我从苹果论坛上的“quinn the eskimo”那里获得了一个解决方案:

问题是在一个线程中完成主机解析,而在其他线程中使用CFHostRef。这很糟糕。

在同一线程中完成的 CFHost 创建(上面的 scomm.host 对象)解决了问题。

I obtained a solution from "quinn the eskimo" on the apple forums:

The problem was resolution of the host done in one thread and the CFHostRef used in other threads. This is bad.

CFHost creation done in the same thread (the scomm.host object, above) fixes problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文