みなさん、こんにちは。ShiKankanのブログです。この記事では、CPUリソースを節約するためのselectメカニズムの使用法を紹介します。マルチスレッドと比較して、そのアプリケーションはよりシンプルで柔軟性があります。
複数のファイルを 監視するには、特定のファイルが読み取り/書き込み可能/異常または時間外である限り、
int select(int nfds、fd_set * readfds、fd_set * writefds、fd_set * exceptionfds、struct timeval * timeout);を返します。
最大ファイルハンドル1は、監視対象のファイルが読み取り可能かどうか、タイムアウト期間は。
監視されている書き込み可能なファイルがあるかどうか。
監視されている異常なファイルがあるかどうか。 int型のnfds個: いくつかの理解とハンドルのソートqqIDへの感謝を:。過去は終わりました、参照用のみ:ハンドルハンドルと同じように、何かを引っ張って持ち上げることができます。また、一般的にインデックスが付けられているデータなど、ハンドルを介して何かを取得することもできます。たとえば、ここにも次のようなインデックスがあります。 現在のプロセスを表すファイル記述子。開いているファイル、継続的に開いているファイルは、 ここではファイル記述子+1と見なすことができます。固定ファイルには、応答するファイルを決定するための固定ファイル記述子があります
百科事典:ファイル記述子:カーネルはファイル記述子を使用してファイルにアクセスします。ファイル記述子は負でない整数です。既存のファイルを開くとき、または新しいファイルを作成するとき、カーネルはファイル記述子を返します。ファイルの読み取りと書き込みでは、ファイル記述子を使用して、読み取りと書き込みを行うファイルを指定する必要もあります。
fd = open(path、O_CREAT | O_RDONLY、0644);つまりfd;
戻り値:
実行が成功した場合は、変更されたファイル記述子の状態の数を返します。0を返した場合は、タイムアウト期間が記述子の状態が変化する前に期限切れ。戻り値;エラーが発生すると-1を返します
。fd_set* readfds:
入力があると 、固定サイズのfd_setのバッファーを返します 。値がFD_SET-SIZEの値fd以上の負の値であるFD_CLR()またはFD_SET()を実行すると、未定義の動作が発生します。さらに、POSIXではfdが有効なファイル記述子である必要があります。 struct timeval * timeoutパラメーターの状況: パラメーターtimeoutがNULLに設定されている場合、選択()がタイムアウトせず、ファイル記述子でイベントが発生するまで選択がブロックされることを意味します。 0:記述子セットのステータスのみを確認し、外部イベントの発生を待たずにすぐに戻ります。特定の時間値:指定された期間にイベントが発生しない場合は、時間をかけて戻ることを選択します。 次のマクロは、これら3つの記述句を処理する方法を提供します 。FD_CLR(inr fd、fd_set * set);記述句セット内の関連するfdビットをクリアするために使用されます FD_ISSET(int fd、fd_set * set);説明句セット内の関連するfdビットが真であるかどうか
FD_SET(int fd、fd_set * set ); fdに関連付けられたセットビットを記述するために使用されるフレーズが設定されます
FD_ZERO(fd_set * set);次のプログラムフラグメントに共通するすべてのビットセットをクリアするために使用される記述されたフレーズ : fs_set readset; FD_ZERO(&readset ); FD_SET(fd、&readset); select(fd + 1、&readset、NULL、NULL、NULL);
選択/ポーリングメカニズムの原則については、ダニエルのブログを参照してください:https://blog.csdn.net/vonzhoufz/article/details/44490675
selectの一般的な使用法は次のとおりです
一般的に、メカニズムの原理はより複雑ですが、ユーザーAPIは非常に単純です。select(int nfds、fd_set * readfds、fd_set * writefds、fd_set * exceptionfds、struct timeval * timeout)関数を呼び出すだけです。
目的:複数のファイルを 監視するには、特定のファイルが読み取り/書き込み可能/異常または時間外である限り、
int select(int nfds、fd_set * readfds、fd_set * writefds、fd_set * exceptionfds、struct timeval * timeout);を返します。
最大ファイルハンドル1は、監視対象のファイルが読み取り可能かどうか、タイムアウト期間は。
監視されている書き込み可能なファイルがあるかどうか。
監視されている異常なファイルがあるかどうか。 int型のnfds個: いくつかの理解とハンドルのソートqqIDへの感謝を:。過去は終わりました、参照用のみ:ハンドルハンドルと同じように、何かを引っ張って持ち上げることができます。また、一般的にインデックスが付けられているデータなど、ハンドルを介して何かを取得することもできます。たとえば、ここにも次のようなインデックスがあります。 現在のプロセスを表すファイル記述子。開いているファイル、継続的に開いているファイルは、 ここではファイル記述子+1と見なすことができます。固定ファイルには、応答するファイルを決定するための固定ファイル記述子があります
百科事典:ファイル記述子:カーネルはファイル記述子を使用してファイルにアクセスします。ファイル記述子は負でない整数です。既存のファイルを開くとき、または新しいファイルを作成するとき、カーネルはファイル記述子を返します。ファイルの読み取りと書き込みでは、ファイル記述子を使用して、読み取りと書き込みを行うファイルを指定する必要もあります。
fd = open(path、O_CREAT | O_RDONLY、0644);つまりfd;
戻り値:
実行が成功した場合は、変更されたファイル記述子の状態の数を返します。0を返した場合は、タイムアウト期間が記述子の状態が変化する前に期限切れ。戻り値;エラーが発生すると-1を返します
。fd_set* readfds:
入力があると 、固定サイズのfd_setのバッファーを返します 。値がFD_SET-SIZEの値fd以上の負の値であるFD_CLR()またはFD_SET()を実行すると、未定義の動作が発生します。さらに、POSIXではfdが有効なファイル記述子である必要があります。 struct timeval * timeoutパラメーターの状況: パラメーターtimeoutがNULLに設定されている場合、選択()がタイムアウトせず、ファイル記述子でイベントが発生するまで選択がブロックされることを意味します。 0:記述子セットのステータスのみを確認し、外部イベントの発生を待たずにすぐに戻ります。特定の時間値:指定された期間にイベントが発生しない場合は、時間をかけて戻ることを選択します。 次のマクロは、これら3つの記述句を処理する方法を提供します 。FD_CLR(inr fd、fd_set * set);記述句セット内の関連するfdビットをクリアするために使用されます FD_ISSET(int fd、fd_set * set);説明句セット内の関連するfdビットが真であるかどうか
FD_SET(int fd、fd_set * set ); fdに関連付けられたセットビットを記述するために使用されるフレーズが設定されます
FD_ZERO(fd_set * set);次のプログラムフラグメントに共通するすべてのビットセットをクリアするために使用される記述されたフレーズ : fs_set readset; FD_ZERO(&readset ); FD_SET(fd、&readset); select(fd + 1、&readset、NULL、NULL、NULL);
if(FD_ISSET(fd、readset){……}
機能ソースコード:タッチスクリーンの選択メカニズムが入力ウェイクアップを実現
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
/**********************************************************************
* 函数名称: main
* 功能描述: select实现低cpu占用操作 触摸屏输入事件监测
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 0 - 成功, 其他值 - 失败
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2018/04/17 V1.0 石侃侃 创建
* 存在问题: select(fd+1, &rfds, NULL, NULL, &tv); 目前已经实现碰触触摸屏唤醒 (select返回)
但是无法识别可读可写 (&rfds在第二第三个参数都有效)而且不能判断open打开的txt文本文件
***********************************************************************/
main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
int fd;
fd=open("/dev/input/event0",O_RDONLY); /* 触摸屏设备 */
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(fd+1, &rfds, NULL, NULL, &tv);/* 超时或者有输入则返回 */
/* Don't rely on the value of tv now! */
if (retval == -1)
perror("select()");
else if (retval)
{
if(FD_ISSET(fd,&rfds))
{
printf("Data is available now ok.\n");
printf("retval=%d\n",retval);
}
else
{
printf("FD_ISSET error");
}
}
else
printf("No data within five seconds.\n"); /* retval=0 */
return 0;
}