歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux中使用select函數

select模型在win32API編程中也很常見,而且和linux中的select函數遵循同樣的berkeley標准,所以函數原型相同。select函數原型:

Ubuntu:

int select( int maxfdp, fd_set * readfds, fd_set * writefds, fd_set * errorfds, struct timeval * timeout);

Win32:

int select( intnfds, fd_set*readfds, fd_set*writefds, fd_set*exceptfds, const struct timeval*timeout);

可以看到是一樣的。不同點是,win32API中的select函數忽略第一個參數。而linux要求第一個參數設置成(參數2~4某個數組中文件描述符的最大值+1)。

下面是ubuntu10.0中使用select函數的一個例子,流程為:

  1. 創建子進程
  2. 子進程通過管道定時發送數據給父進程
  3. 父進程通過select同時監聽管道數據和用戶輸入
  4. 父進程等待子進程退出

Ubuntu10.0.4:

源代碼文件select.cpp:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>// waitpid
#include <sys/types.h>// waitpid
#include <string.h>// strlen
/*
comment:
pipe is used between two processes on the same computer.
*/
#define TIMES 50
int main(){
 int pipefds[2];
 if( -1 == pipe( pipefds)){
  printf( "Error when create pipes\n");
 }else{
  int i;
  pid_t pid = fork();
  if( 0 == pid){// child
   printf( "child running\n");
   close( pipefds[0]);
   for( i = 0; i < TIMES; ++ i){
    write( pipefds[1], "iamagoodguy", strlen( "iamagoodguy"));
    sleep( 1);
   }
  }else{
   printf( "parent running\n");
   char buf[256];
   close( pipefds[1]);
   fd_set readfdset;// file descriptor set
   for( i = 0; i < TIMES; ++ i){
    FD_ZERO( & readfdset);
    FD_SET( pipefds[0], & readfdset);// add read file descriptor
    FD_SET( 0, & readfdset);// add standard input
    select( pipefds[0]+1, & readfdset, NULL, NULL, NULL);
    if( FD_ISSET( pipefds[0], & readfdset)){
     buf[ read( pipefds[0], buf, 256)] = '\0';
     printf( "Receive:%s\n", buf);
    }
    if( FD_ISSET( 0, & readfdset)){
     buf[ read( 0, buf, 256)] = '\0';
     printf( "Print:%s\n", buf);
    }
   }
   int status;
   wait( & status);
  }
 }
 return 0;
}

還需要一個Makefile:

select: select.cpp
 g++ $< -o $@

然後在命令行中鍵入:

make select
./select

運行截圖:

注意點

父進程必須等待子進程結束。如果父進程先於子進程結束,子進程成為死進程。

每次調用select後參數2都會被改變,下次調用select前必須重新設置。

Copyright © Linux教程網 All Rights Reserved