Chinaunix首页 | 论坛 | 博客
  • 博客访问: 25371
  • 博文数量: 6
  • 博客积分: 138
  • 博客等级: 入伍新兵
  • 技术积分: 50
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-26 11:01
文章分类
文章存档

2011年(6)

最近访客

分类: LINUX

2011-09-28 17:23:42

$ cat pipe.c
#include
#include
#include
#include

int fdctl[2];// 这个管道在建立线程之前建立。创建线程之后,两个线程各连接其中一端。因为不存在 fork 导致的 fd 复制,所以不需要像普通多进程环境一样 close 一端

// 控制线程,使用 fdctl[0]
void *thfun( void *arg )
{
  int i;
  for ( i = 0; i < 3; ++i )
    {
      printf( "%d sec\n", i );
      sleep( 1 );
    }

  close( fdctl[0] );// 当一个 fd 被关闭的时候,会触发 readable / writable 事件
}

// 主线程 select 阻塞
int main()
{
  fd_set rdset;
  int maxfd = 2;
  pipe( fdctl );
  maxfd = fdctl[1];
  FD_ZERO( &rdset );
  FD_SET( STDIN_FILENO, &rdset ); // 需要被监测的 fd,通常为 socket。这里用 stdin 代替
  FD_SET( fdctl[1], &rdset ); // 控制管道。虽然 close 管道一端会同时引发 readable / writable 事件,但是由于 pipe 有缓冲,默认情况下 pipe 就是 writable 的,所以使用 rdset 进行监测

  pthread_t tid;
  pthread_create( &tid, NULL, thfun, NULL );

  int res = select( maxfd + 1, &rdset, NULL, NULL, NULL ); // 同时监测 socket 和控制管道。writable set 也可以同时监测其它 fd
  printf( "select() returned with %d\n", res );
  if ( res == 1 ) {
    if ( FD_ISSET( fdctl[1], &rdset ) ) // 是否控制管道产生的事件?
      printf( "Ctrled Exit\n" ); // 如果是,则是由于控制线程触发。select 阻塞被成功打断
    else
      deal_with_fd(); // 不是控制管道的信息;处理来自 socket 的信息
  }
  return 0;
}
阅读(1775) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~