- 論壇徽章:
- 0
|
- $ cat pipe.c
- #include <sys/select.h>
- #include <pthread.h>
- #include <unistd.h>
- #include <stdio.h>
- int fdctl[2];// 這個(gè)管道在建立線程之前建立。創(chuàng)建線程之后,兩個(gè)線程各連接其中一端。因?yàn)椴淮嬖?fork 導(dǎo)致的 fd 復(fù)制,所以不需要像普通多進(jìn)程環(huán)境一樣 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] );// 當(dāng)一個(gè) fd 被關(guān)閉的時(shí)候,會(huì)觸發(fā) readable / writable 事件
- }
- // 主線程 select 阻塞
- int main()
- {
- fd_set rdset;
- int maxfd = 2;
- pipe( fdctl );
- maxfd = fdctl[1];
- FD_ZERO( &rdset );
- FD_SET( STDIN_FILENO, &rdset ); // 需要被監(jiān)測的 fd,通常為 socket。這里用 stdin 代替
- FD_SET( fdctl[1], &rdset ); // 控制管道。雖然 close 管道一端會(huì)同時(shí)引發(fā) readable / writable 事件,但是由于 pipe 有緩沖,默認(rèn)情況下 pipe 就是 writable 的,所以使用 rdset 進(jìn)行監(jiān)測
- pthread_t tid;
- pthread_create( &tid, NULL, thfun, NULL );
- int res = select( maxfd + 1, &rdset, NULL, NULL, NULL ); // 同時(shí)監(jiān)測 socket 和控制管道。writable set 也可以同時(shí)監(jiān)測其它 fd
- printf( "select() returned with %d\n", res );
- if ( res == 1 ) {
- if ( FD_ISSET( fdctl[1], &rdset ) ) // 是否控制管道產(chǎn)生的事件?
- printf( "Ctrled Exit\n" ); // 如果是,則是由于控制線程觸發(fā)。select 阻塞被成功打斷
- else
- deal_with_fd(); // 不是控制管道的信息;處理來自 socket 的信息
- }
- return 0;
- }
復(fù)制代碼
[ 本帖最后由 wolf0403 于 2006-8-12 20:48 編輯 ] |
|