软件开发: 03 2009存档

异步recv

| | Comments (0) | TrackBacks (0)
可以通过

    int opts;
    opts=fcntl(fd, F_GETFL);
    if (opts < 0)
    {
        perror("fcntl failed\n");
        return;
    }
    opts = opts | O_NONBLOCK;
    if(fcntl(fd, F_SETFL, opts) < 0)
    {
        perror("fcntl failed\n");
        return;
    }
    return;

把 fd 设为非阻塞模式(non-blocking)
在recv时

while(rs)
{
  buflen = recv(activeevents[i].data.fd, buf, sizeof(buf), 0);
  if(buflen < 0)
  {
    // 由于是非阻塞的模式,所以当errno为EAGAIN时,表示当前缓冲区已无数据可读
    // 在这里就当作是该次事件已处理处.
    if(errno == EAGAIN)
     break;
    else
     return;
   }
   else if(buflen == 0)
   {
     // 这里表示对端的socket已正常关闭.
   }
   if(buflen == sizeof(buf)
     rs = 1;   // 需要再次读取
   else
     rs = 0;
}

这段recv代码摘自http://blog.chinaunix.net/u/14063/showart_377118.html,今天帮了大忙。在非阻塞模式下,recv返回的buflen可能小于用户要求的接收长度(recv第三个参数);而在阻塞模式(blocking)下,毫无疑问,recv会把进程挂住,直到收到用户要求的长度为止。

gcc -O3

| | Comments (0) | TrackBacks (0)
int i;
for(i=0; i<100; i++)
{
      i = i;
}
本来想用上面这样的循环来延迟时间,结果,在gcc用 -O3 编译以后,这个“无用循环”被优化掉了。再试了试
int i, j;
for(i=0; i<100; i++)
{
      j = i*i;
}
不行,还是被优化掉了。最后只能这样:
int i, j;
for(i=0; i<100; i++)
{
      j = i*i;
}

if(j > 1000)
......

j现在变成了“循环后还要用到的变量”,这样,gcc就无法认出这是无用循环了。

看来 gcc -O3 还是很厉害的。
      看linux内核很容易被struct address_space 这个结构迷惑,它是代表某个地址空间吗?实际上不是的,它是用于管理文件(struct inode)映射到内存的页面(struct page)的;与之对应,address_space_operations 就是用来操作该文件映射到内存的页面,比如把内存中的修改写回文件、从文件中读入数据到页面缓冲等。
      参考下面这张图,摘自《深入理解linux虚拟内存管理》,对理解linux内存管理颇有帮助

linux