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

Linux設備驅動中的異步通知

異步通知的概念:

一旦設備就緒,主動通知應用程序。這樣應用程序根本不需要查詢設備狀態。 

阻塞,非阻塞和異步:

-阻塞IO是等待設備可訪問後再訪問

-非阻塞IO是查詢設備是否可以訪問

-異步通知是設備通知自身可以訪問 

為了使支持異步通知機制,驅動程序應該涉及以下3項工作。

支持F_SETOWN命令,能在這個控制命令處理。 

處理FASYNC標志更變的函數

Int fasync_helper(int fd, struct file*filp, int mode, struct fasync_struct **fa);

釋放信號用的函數

Void kill_fasync(struct fasync_struct **fa,int sig, int band);

void kill_fasync(struct fasync_struct **fp,int sig, int band)

{

/*First a quick test without locking: usually

* the list is empty.

*/

if(*fp) {

read_lock(&fasync_lock);

/*reread *fp after obtaining the lock */

__kill_fasync(*fp,sig, band);

read_unlock(&fasync_lock);

}

}

 

void __kill_fasync(struct fasync_struct*fa, int sig, int band)

{

while(fa) {

structfown_struct * fown;

if(fa->magic != FASYNC_MAGIC) {

printk(KERN_ERR"kill_fasync: bad magic number in "

"fasync_struct!\n");

return;

}

fown= &fa->fa_file->f_owner;

/*Don't send SIGURG to processes which have not set a

queued signum: SIGURG has its own defaultsignalling

mechanism. */

if(!(sig == SIGURG && fown->signum == 0))

send_sigio(fown,fa->fa_fd, band);

fa= fa->fa_next;

}

}

 

void send_sigio(struct fown_struct *fown,int fd, int band)

{

structtask_struct *p;

enumpid_type type;

structpid *pid;

intgroup = 1;

 

read_lock(&fown->lock);

 

type= fown->pid_type;

if(type == PIDTYPE_MAX) {

group= 0;

type= PIDTYPE_PID;

}

 

pid= fown->pid;

if(!pid)

gotoout_unlock_fown;

 

read_lock(&tasklist_lock);

do_each_pid_task(pid, type, p) {

send_sigio_to_task(p,fown, fd, band, group);

} while_each_pid_task(pid, type, p);

read_unlock(&tasklist_lock);

out_unlock_fown:

read_unlock(&fown->lock);

}

通過內核,給所有的進程發送信號。 

用戶對應進程可以接受該信號,並作處理。

用戶進程要做的是:

1.綁定信號和信號處理函數

Signal(SIGIO,input_handler)

2.設定本進程為某個標准輸入文件的擁有者。這樣內核就知道信號發送給那個進程。

Fcntl(STDIN_FILENO,F_SETNO,getpid());

3.對輸入文件設定異步標志位。

Fcntl(STDIN_FILENO,F_SETFL,oflags | FASYNC);

Copyright © Linux教程網 All Rights Reserved