- 论坛徽章:
- 0
|
版本5.02
在一个非阻塞的socket上读取8字节,并不能保证每次都读取到8字节,若由于系统繁忙没有读取到8字节,将导致异常。
1)线程间的通知采用pipe来产生两个socket (storage_service.c 1639)
if (pipe(pThreadData->thread_data.pipe_fds) != 0)
{
result = errno != 0 ? errno : EPERM;
logError("file: "__FILE__", line: %d, " \
"call pipe fail, " \
"errno: %d, error info: %s", \
__LINE__, result, STRERROR(result));
break;
}
2)将读socket设置成非阻塞,写socket还是阻塞的 (storage_service.c 1650)
if ((result=fd_add_flags(pThreadData->thread_data.pipe_fds[0], \
O_NONBLOCK | O_NOATIME)) != 0)
{
break;
}
3)创建一个任务并将该任务的地址写入到 pipe_fds[1] (storage_service.c 174
task_addr = (long)pTask;
write(pThreadData->thread_data.pipe_fds[1], &task_addr, sizeof(task_addr)) != sizeof(task_addr)
4) pipe_fds[0]读事件处理函数,他这里直接使用一个read读取8字节,因为是非阻塞并不能保证都会读到8个字节吧
如果没有读到8个字节那么这个task_addr就是异常的吧 (storage_nio.c 134)
while (1)
{
if ((bytes=read(sock, &task_addr, sizeof(task_addr))) < 0)
{
if (!(errno == EAGAIN || errno == EWOULDBLOCK))
{
logError("file: "__FILE__", line: %d, " \
"call read failed, " \
"errno: %d, error info: %s", \
__LINE__, errno, STRERROR(errno));
}
break;
}
else if (bytes == 0)
{
logError("file: "__FILE__", line: %d, " \
"call read failed, end of file", __LINE__);
break;
}
pTask = (struct fast_task_info *)task_addr;
|
|