当我尝试调度单个线程来轮询 unix 套接字时,我注意到一些奇怪的行为。当我在 osx 10.6.8 上测试代码时,代码崩溃,我看到超过 1 个线程在运行代码。奇怪的是,在 osx 10.7.5 上,当它崩溃时,我只看到它在一个线程上运行。
在我的 AppDelegate 中,我像这样(一次)调度线程:
[pp performSelectorInBackground:@selector(runloop) withObject:nil];
pp 是 My IPC 类的一个实例。
在我的 IPC 类中,runloop 是一些 C 代码的包装器
@implementation IPC
-(void) runloop
{
ipc_busy = 0;
unixsocket_runloop();
}
runloop 旨在等待单个连接(每个运行时)然后处理程序等待数据包,直到程序终止。C 代码如下所示 -
/**
* Waits for a connection and dispatches the socket handler
* No need to fork since we will only ever have a single connection per program launch
*/
int unixsocket_runloop()
{
int connection_fd;
socklen_t address_length;
while((connection_fd = accept(socket_fd,
(struct sockaddr *) &address,
&address_length)) > -1)
{
return unixsocket_handler(connection_fd);
}
return 0; // for posterity
}
这是连接处理程序 -
/**
* Handles the connection from the client
* loops infinitely and reads from the socket when there is a message
* Stores message into a ring buffer of buffers
*/
int unixsocket_handler(int connection_fd)
{
size_t nbytes;
char readbuffer[USBUFSIZE];
bzero(readbuffer,USBUFSIZE);
while((nbytes = read(connection_fd, readbuffer, USBUFSIZE)))
{
// store in buffer
bufPut(readbuffer,nbytes);
bzero(readbuffer,USBUFSIZE);
}
close(connection_fd);
return 0;
}
在我的堆栈跟踪中,我看到这个 unixsocket_runloop 发生在 2 个线程中。虽然我不认为这是崩溃的根本原因,但这是我想解决的意外行为。
我使用自己的套接字类滚动的唯一原因是我在开源社区中看到的很多选项都硬连接到 TCP。尤其是吸引人的 cocoaAsyncSocket 类。