精华内容
下载资源
问答
  • 首先,本文讨论的单线程的问题,多CPU多线程的情况不在考虑范围,不过思想都...异步,只是简单地向操作系统注册完一个函数,操作系统在IO操作完成后,用信号通知该进程。例如[2], 第一行,signal不必等到 on_...

    首先,本文讨论的单线程的问题,多CPU多线程的情况不在考虑范围,不过思想都是一样的。

    同步和异步

    同步是说当前代码不执行完,后面的代码,或者严谨点说,后面的指令将不执行。

    例如[1],下列,select 函数不返回,下面的代码将不会执行。

     

    异步,只是简单地向操作系统注册完一个函数,操作系统在IO操作完成后,用信号通知该进程。例如[2],

    第一行,signal不必等到 on_input 函数执行完才执行后面的指令,而是立即返回。那 on_input 什么时候执行呢,进程通过什么方式知道该执行了呢?信号,当内核发送一个特有的信号,这里是SIGIO,进程将执行 on_input 函数,执行完再回到原来的地方。

     

    阻塞和非阻塞

    阻塞和非阻塞是说,进程是否由运行态变成阻塞态,这时,操作系统将会将该进程挂在阻塞队列上,并选择其他就绪进程上CPU,所以,阻塞对当前进程是种时间和效率上的浪费。阻塞是说,当前操作会引起进程进入阻塞态,例如普通的打开文件操作,就会阻塞自己,直到内核返回。而非阻塞是否,当前操作不会引起进入阻塞态。

    那么同步阻塞,同步非阻塞,异步非阻塞,异步阻塞是说什么呢?

    其实,最后一个名词是个伪命题,异步不会引起进程进入阻塞态,例如上面的注册回调函数的操作。

    同步阻塞就是我们普通的打开文件操作,同步非阻塞,是指,进程调用select等系统调用[3],而且把该系统调用的超时时间设置为0时,select函数会立即返回,不会阻塞当前进程,不会引起进程进入阻塞态。而且,后面的指令也必须在select等执行完之后再执行,这二者一组合,就变成了同步非阻塞。而异步非阻塞的意思就是异步操作了,上面已经提过了。

    参考资料:

    1. ostep第33章 ostep

    2. 《Unix/Linux编程实践教程》 第7章12节,第15章第2节

    3.   select是同步阻塞还是非阻塞

    展开全文
  • 异步通知意思是:一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这一点非常类似于硬件上“中断”的概念,比较准确的称谓“信号驱动的异步I/O”。信号在软件层次上对中断机制的一...

    异步通知的意思是:一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这一点非常类似于硬件上“中断”的概念,比较准确的称谓是“信号驱动的异步I/O”。信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
    阻塞I/O意味着一直等待设备可访问后再访问,非阻塞I/O中使用poll()意味着查询设备是否可访问,而异步通知则意味着设备通知用户自身可访问,之后用户再进行I/O处理。由此可见,这几种I/O方式可以相互补充。Linux信号及其定义
    一个信号被捕获的意思是当一个信号到达时有相应的代码处理它。如果一个信号没有被这个进程所捕获,内核将采用默认行为处理。
    信号的接收
    在用户程序中,为了捕获信号,可以使用signal()函数来设置对应的信号处理函数:
    void (*signal (int signum, void (*handler))(int ))) (int);
    可以分解为:
    typedef void (*signadler_t) (int);
    sighandler_t signal(int signum, sighandler_t handler);
    第一个参数signum指定信号的值,第二个函数指针参数指定针对前面信号值的处理函数,若为SIG_IGN,表示忽略该信号;若为SIG_DFL,表示采用系统默认的方式处理信号;若为用户自定义的函数,则信号被捕获后,该函数将被执行。
    如果signal()调用成功,它返回最后一次为信号signum绑定的处理函数的handler值,失败则返回SIG_ERR。

    在进程执行时,按下“Ctrl+C”将向其发出SIGINT信号,正在运行kill的进程将向其发出SIGTERM信
    号,以下代码中的进程可捕获这两个信号并输出信号值。
    void sigterm_handler(int signo)
    {
    printf(“Have caught sig N.O. %d\n”, signo);
    exit(0);

    }
    int main(void)
    {
    signal(SIGINT, sigterm_handler);
    signal(SIGTERM, sigterm_handler);
    while(1);
    return 0;
    }

    除了signal()函数外,sigaction()函数可用于改变进程接收到特定信号后的行为,它的原型为:
    int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
    该函数的第一个参数为信号的值,可以是除SIGKILL及SIGSTOP外的任何一个特定有效的信号。第二个参数是指向结构体sigaction的一个实例的指针,在结构体sigaction的实例中,指定了对特定信号的处理函数,若为空,则进程会以缺省方式对信号处理;第三个参数oldact指向的对象用来保存原来对相应信号的处理函数,可指定oldact为NULL。如果把第二、第三个参数都设为NULL,那么该函数可用于检查信号的有效性.

    先来看一个使用信号实现异步通知的例子,它通过signal(SIGIO,input_handler)对标准输入文件描述符STDIN_FILENO启动信号机制。用户输入后,应用程序将接收到SIGIO信号,其处理函数input_handler()将被调用.

    include

    include

    include

    include

    include

    include

    define MAX_LEX 100

    void input_handler(int num)
    {
    char data[MAX_LEN];
    int len;
    // 读取并输出STDIN_FILENO上的输入
    len = read(STDIN_FILENO, &data, MAX_LEN);
    data[len] = 0;
    printf(“input available: %d\n”, data);
    }

    void main()
    {
    int oflags;
    // 启动信号驱动机制
    signal(SIGIO, input_handler); // 将SIGIO信号同input_handler函数关联起来,一旦产生SIGIO信号,就会执行input_handler函数
    // STDIN_FILENO是打开的设备文件描述符,F_SETOWN用来决定操作是干什么的,getpid()是个系统调用,功能是返回当前进程
    //的进程号,整个函数的功能是STDIN_FILENO设置这个设备文件拥有者为当前进程
    fcntl(STDIN_FILENO, F_SETOWN, getpid());
    oflags = fcntl(STDIN_FILENO, F_SETFL, ofags | FASYNC); // 得到打开文件描述符的状态
    // 设置文件描述符的状态为oflags | FASYNC属性,一旦文件描述符被设置程具有FASYNC属性的状态,也就是将设备文件切换到
    // 异步操作模式,这时系统会自动调用驱动程序的fasync方法。
    fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);
    // 最后进入一个死循环,仅为保持进程不终止,如果程序中没有这个死循环会立即执行完毕
    while(1);
    }

    ssize_t (read)(struct file *filp, char __user *buffer, size_t size, loff_t p);
    filp:为进行读取信息的目标文件;
    buffer:为放置信息的缓冲区(即用户空间地址);
    size:为要读取的信息长度;
    p:为要读取的位置相对文件开头的偏移,在读取信息后,这个指针一般都会移动,移动的值为要读取的信息的长度;

    ssize_t (write) (struct file *filp, char __user buffer, size_t count , loff_t *ppos);
    filp :为目标文件结构体指针;
    buffer :为要写入文件的信息缓冲区;
    count :为要写入信息的长度;
    ppos :为当前的偏移位置,这个值通常是用来判断写文件是否越界

    fcntl()

    include

    include

    include

    include

    include

    include

    展开全文
  •  异步通知意思是: 一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这一点非常类似于硬件上“中断”的概念,比较准确的称谓“信号驱动的异步I/O”。信号在软件层次上对中断机制的...

    1. 基本概念

        异步通知的意思是: 一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这一点非常类似于硬件上“中断”的概念,比较准确的称谓是“信号驱动的异步I/O”。信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
        阻塞I/O意味着一直等待设备可访问后再访问,非阻塞I/O中使用poll()意味着查询设备是否可访问,而异步通知则意味着设备通知用户自身可访问,之后用户再进行I/O处理。由此可见,这几种I/O方式可以相互补充。

    2. 使用异步通知

        使用信号进行进程间通信(IPC)是UNIX中的一种传统机制,Linux也支持这种机制。在Linux中,异步通知使用信号来实现, Linux中可用的信号及其定义如下: 

        除了SIGSTOPSIGKILL两个信号外,进程能够忽略或捕获其他的全部信号。一个信号被捕获的意思是当一个信号到达时有相应的代码处理它,如果一个信号没有被这个进程所捕获,内核将采用默认行为处理。

    2.1 信号的接收

        在用户程序中, 为了捕获信号, 可以使用signal() 函数来设置对应信号的处理函数:

    void (*signal(int signum, void (*handler))(int)))(int);

        第一个参数指定信号的值,第二个参数指定针对前面信号值的处理函数,若为SIG_IGN,表示忽略该信号;若为SIG_DFL,表示采用系统默认方式处理信号;若为用户自定义的函数,则信号被捕获到后,该函数将被执行。如果signal() 调用成功,它返回最后一次为信号signum绑定的处理函数的handler值,失败则返回SIG_ERR。
        信号接收部分完全在应用程序中,完整应用程序fasync_text.c代码如下:

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <poll.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    /* fasync_text
      */
    void my_signal_fun(int signum)
    {
    	printf("received signal SIGIO!\n");
    }
    
    int main(int argc, char **argv)
    {
    	int Oflags;
    	int fd;
    	
    	signal(SIGIO, my_signal_fun);
    	
    	fd = open("/dev/test", O_RDWR);
    	if (fd < 0)
    	{
    		printf("can't open /dev/test !\n");
    	}
    
    	fcntl(fd, F_SETOWN, getpid());    //定义该驱动要发送信号给哪个进程(PID)
    	Oflags = fcntl(fd, F_GETFL); 
    	fcntl(fd, F_SETFL, Oflags | FASYNC);
    
    	while (1)
    	{
    		sleep(1000);
    	}
    	return 0;
    }
    
    

        fcntl(fd, F_SETOWN, getpid());
        Oflags = fcntl(fd, F_GETFL);
        fcntl(fd, F_SETFL, Oflags | FASYNC);

        这3行代码的作用是为了能在用户空间中处理一个设备释放的信号, 分别的作用是:
        (1) 通过F_SETOWN IO控制命令设置设备文件的拥有者为本进程, 这样从设备驱动发出的信号才能被本进程接收到。
        (2) 通过F_SETFL IO控制命令设置设备文件以支持FASYNC, 即异步通知模式。
        (3) 通过signal( ) 函数连接信号和信号处理函数。

        这样,当应用程序接收到SIGIO这个信号时,就会调用my_signal_fun()函数了,就可以实现设备驱动通知应用程序去执行某些工作了。

    2.2 信号的释放

        应用程序端负责捕获信号,则设备驱动负责释放信号,需要在设备驱动程序中增加信号释放的相关代码。
        为了使设备支持异步通知机制, 驱动程序中涉及3项工作:
        (1) 支持F_SETOWN命令,能在这个控制命令处理中设置filp->f_owner为对应进程ID。不过此项工作已由内核完成,设备驱动无须处理。
        (2) 支持F_SETFL命令的处理,每当FASYNC标志改变时,驱动程序中的fasync()函数将得以执行。因此,驱动中应该实现fasync() 函数。
        (3) 在设备资源可获得时,调用kill_fasync()函数激发相应的信号。

        上述的3项工作和应用程序中的3项是对应的,他们之间的关系,如下图:


    完整驱动程序fasync_drv.c代码如下:

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/fs.h>
    #include <linux/init.h>
    #include <linux/interrupt.h>
    #include <linux/sched.h>
    #include <linux/init.h>
    #include <linux/timer.h>
    #include <linux/cdev.h>
    
    
    int major;
    static struct cdev test_cdev;
    static struct class *test_class;
     
    struct timer_list timer;    //定义一个定时器
    static struct fasync_struct *test_async;
    
    /*每隔5秒发送一次SIGIO信号*/
    void test_function(unsigned long arg)
    {
    	mod_timer(&timer, jiffies + (5*HZ));	//重新设置定时器,每隔5秒执行一次
    
    	printk("send signal SIGIO to user!\n");
    	kill_fasync(&test_async, SIGIO, POLL_IN);
    }
    
    static int test_open(struct inode *inode, struct file *file)
    {
    	init_timer(&timer);     		//初始化定时器
        timer.expires = jiffies+(5*HZ); //设定超时时间,5秒
        timer.data = 5;    				//传递给定时器超时函数的值
        timer.function = test_function; //设置定时器超时函数
        add_timer(&timer); 				//添加定时器,定时器开始生效
    
    	return 0;
    }
    
    static int test_fasync(int fd, struct file * file, int on)
    {
    	printk("driver: test_fasync\n");
    	return fasync_helper(fd, file, on, &test_async);
    }
    
    int test_close(struct inode *inode, struct file *file)
    {	
    	del_timer(&timer);		 //删除定时器
    	test_fasync(-1, file, 0);	 //将文件从异步通知列表中删除
    	return 0;
    }
    
    static struct file_operations test_fops = {
        .owner   =  THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
        .open    =  test_open,     
        .fasync  =	test_fasync,
        .release =  test_close,
    };
    
    static int test_init(void)
    {
    	int result;
    	dev_t devid = MKDEV(major, 0);	//从主设备号major,次设备号0得到dev_t类型
    	if (major) 
    	{
    		result=register_chrdev_region(devid, 1, "test");	//注册字符设备
    	} 
    	else 
    	{
    		result=alloc_chrdev_region(&devid, 0, 1, "test");	//注册字符设备
    		major = MAJOR(devid);		//从dev_t类型得到主设备
    	}
    	if(result<0)
    		return result;
    	
    	cdev_init(&test_cdev, &test_fops);
    	cdev_add(&test_cdev, devid, 1);
    	test_class = class_create(THIS_MODULE, "test_drv");
    	class_device_create(test_class, NULL, MKDEV(major, 0), NULL, "test"); /* /dev/buttons */
    
    	return 0;
    }
    
    static void test_exit(void)
    {
    	class_device_destroy(test_class, MKDEV(major, 0));
    	class_destroy(test_class);
    	cdev_del(&test_cdev);
    	unregister_chrdev_region(MKDEV(major, 0), 1);
    }
    
    module_init(test_init);
    module_exit(test_exit);
    MODULE_AUTHOR("LVZHENHAI");
    MODULE_LICENSE("GPL");
    
    

    Makefile如下:

    KERN_DIR = /work/system/linux-2.6.22.6    //内核目录
     
    all:
    	make -C $(KERN_DIR) M=`pwd` modules 
     
    clean:
    	make -C $(KERN_DIR) M=`pwd` modules clean
    	rm -rf modules.order
     
    obj-m	+= fasync_drv.o

    3. 测试

    内核:linux-2.6.22.6
    编译器:arm-linux-gcc-3.4.5
    环境:ubuntu9.10

    fasync_drv.c、fasync_test.c、Makefile三个文件放入网络文件系统内,在ubuntu该目录下执行:
        make
        arm-linux-gcc -o fasync_test fasync_test.c

    在挂载了网络文件系统的开发板上进入相同目录,执行“ls”查看:

    装载驱动:
        insmod fasync_drv.ko
    运行测试程序:
        ./fasync_test
    结果如下:

    每隔5秒都会打印:
        send signal SIGIO to user!
        received signal SIGIO!

    4. 程序说明

    应用程序open打开驱动,驱动里就会创建一个5秒循环启动的定时器,然后应用程序设置好异步通知模式后,直接进入while死循环里。驱动程序每5秒启动定时器函数发送SIGIO信号,打印send signal SIGIO to user!,应用程序就会接受到信号并打印received signal SIGIO!。

     

    展开全文
  • 异步通知意思是:一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这一点非常类似于硬件上“中断”的概念,比较准确的称谓“信号驱动的异步I/O”.信号在软件层次上对中断机制的一种模拟...

    前言

    异步通知的意思是:一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这一点非常类似于硬件上“中断”的概念,比较准确的称谓是“信号驱动的异步I/O”.信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
    在这里插入图片描述

    应用层

    实现异步通知机制,用户程序涉及2项工作,首先,得指定一个进程作为文件的“属主(owner)”.当应用程序使用fcntl系统调用执行F_SETOWN命令时,属主进程的进程ID号就被保存在filp->f_owner中.这一步是必需的,目的是告诉内核将信号发给谁,也就是发给哪个进程.然后为了真正启动异步通知机制,用户程序还必须在设备中设置FASYNC标志,这通过fcntl的F_SETFL命令完成的,文件打开时,FASYNC标志被默认为是清除的.,每当FASYNC标志改变时,驱动程序中的fasync()函数将得以执行。.执行完这两个步骤之后,内核就可以在新数据到达时通过调用kill_fasync()函数请求发送一个SIGIO信号给应用层,该信号被发送到存放在filp->f_owner中的进程(如果是负值就是进程组)
    在这里插入图片描述

    内核层

    根据内核源码来看看调用过程,应用层调用fcntl(),会进行系统调用sys_fcntl(),接着调用do_fcntl(),再根据cmd调用相应的操作函数
    sys_fcntl

    asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
    {	
    	struct file *filp;
    	long err = -EBADF;
    
    	filp = fget(fd);//通过文件描述符获得相应的文件指针
    	if (!filp)
    		goto out;
    
    	err = security_file_fcntl(filp, cmd, arg);//调用do_fcntl函数
    	if (err) {
    		fput(filp);
    		return err;
    	}
    
    	err = do_fcntl(fd, cmd, arg, filp);
    
     	fput(filp);
    out:
    	return err;
    }
    

    do_fcntl

    static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
    		struct file *filp)
    {
    	long err = -EINVAL;
        ......
    	case F_GETFL: //返回文件标志
    		err = filp->f_flags;
    		break;
    	case F_SETFL:
    		err = setfl(fd, filp, arg);//转调用setfl函数
    		break;
    	case F_SETOWN:
    		err = f_setown(filp, arg, 1);//转调用f_setown函数
    		break;
    	.......
    	default:
    		break;
    	}
    	return err;
    }
    

    setfl函数的内部实现

    static int setfl(int fd, struct file * filp, unsigned long arg)
    {
        struct inode * inode = filp->f_dentry->d_inode;
        int error = 0;
        ……
        lock_kernel();
        //下面这个判断语句有点意思,是一个边缘触发
        //FASYNC标志从0变为1的时候为真
        if ((arg ^ filp->f_flags) & FASYNC) {//FASYNC标志发生了变化
            if (filp->f_op && filp->f_op->fasync) {
                error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);//每当FASYNC标志改变时,驱动程序中的fasync()函数将得以执行。
                if (error < 0)
                    goto out;
            }
        }
    
        filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
     out:
        unlock_kernel();
        return error;
    }t
    

    f_setown函数的内部实现

    int f_setown(struct file *filp, unsigned long arg, int force)
    {
        int err;
    
        err = security_file_set_fowner(filp);
        if (err)
            return err;
    
        f_modown(filp, arg, current->uid, current->euid, force);//调用f_modown函数
        return 0;
    }
    
    
    static void f_modown(struct file *filp, unsigned long pid,
                         uid_t uid, uid_t euid, int force)
    {
        write_lock_irq(&filp->f_owner.lock);
        //设置对应的pid,uid,euid
        if (force || !filp->f_owner.pid) {
            filp->f_owner.pid = pid;
            filp->f_owner.uid = uid;
            filp->f_owner.euid = euid;
        }
        write_unlock_irq(&filp->f_owner.lock);
    }
    

    相关的数据结构和函数

    struct fasync_struct {
        int magic;
        int fa_fd;//文件描述符
        struct  fasync_struct   *fa_next; /* singly linked list *///异步通知队列
        struct  file        *fa_file;//文件指针
    };
    

    处理FASYNC标志变更的函数

    int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
    
    int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
    {
        struct fasync_struct *fa, **fp;
        struct fasync_struct *new = NULL;
        int result = 0;
    
        if (on) {
            new = kmem_cache_alloc(fasync_cache, SLAB_KERNEL);//创建对象,slab分配器
            if (!new)
                return -ENOMEM;
        }
        write_lock_irq(&fasync_lock);
        //遍历整个异步通知队列,看是否存在对应的文件指针
        for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
            if (fa->fa_file == filp) {//已存在
                if(on) {
                    fa->fa_fd = fd;//文件描述符赋值
                    kmem_cache_free(fasync_cache, new);//销毁刚创建的对象
                } else {
                    *fp = fa->fa_next;//继续遍历
                    kmem_cache_free(fasync_cache, fa);//删除非目标对象
                    result = 1;
                }
                goto out;//找到了
            }
        }
    
    //所谓的把进程添加到异步通知队列中,实则是将文件指针关联到异步结构体对象,然后将该对象挂载在异步通知队列中(等待队列也是这个原理)
    
        if (on) {//不存在
            new->magic = FASYNC_MAGIC;
            new->fa_file = filp;//指定文件指针
            new->fa_fd = fd;//指定文件描述符
            new->fa_next = *fapp;//挂载在异步通知队列中
            *fapp = new;//挂载
            result = 1;
        }
    out:
        write_unlock_irq(&fasync_lock);
        return result;
    }
    

    释放信号用的函数

    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) {
            struct fown_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;//这就是应用层使用F_SETOWN的意义,让其通过异步对象的文件指针知道其主进程
            if (!(sig == SIGURG && fown->signum == 0))
                send_sigio(fown, fa->fa_fd, band);//向主进程发送信号,也就是向我们的执行了fcntl(fd,F_SETOWN,getpid())命令的应用程序发送信号
            fa = fa->fa_next;
        }
    }
    

    当一个打开的文件的FASYNC标志被修改时,调用fasync_helper函数以便从相关的进程表中添加或删除文件.当数据到达时,可使用kill_fasync函数通知所有的相关进程。

    展开全文
  • 异步通知意思是: 一旦设备就绪, 则驱动主动通知应用程序, 这样应用程序根本就不需要查询设备状态, 这一点非常类似于硬件上“中断”的概念, 比较准确的称谓“信号驱动的异步I/O”。 信号在软件层次上对...
  • 前面已经说了阻塞与非阻塞的访问方式,这里我们就继续说下异步通知的机制。 什么是异步通知呢?异步通知的意思就是,一旦设备就绪,则主动通知应用程序,应用程序根本就不需要查询设备状态...在linux中,异步通知是使
  • 什么是异步通知:很简单,一旦设备准备好,就主动通知应用程序,这种情况下应用程序就不需要查询设备状态, 特像硬件上常提的“中断的概念”。 比较准确的说法其实应该叫做“信号驱动的异步I/O”,信号在软件层次上...
  • 扫盲,什么叫同步异步 ...至于执行的顺序是什么,这是不确定的。而某个任务要执行到什么时间结束,这要看分给这个任务的CPU时间。时间到了就结束(分时系统,大部分情况都是这样)。 为什么需要异...
  • Android bindService一个异步过程

    千次阅读 2018-01-16 20:49:13
    Android中bindService一个异步的过程,什么意思呢?使用bindService无非想获得一个Binder服务的Proxy,但这个代理获取到的时机并非由bindService发起端控制,而是由Service端来控制,也就是说bindService之后,...
  • 同步和异步另外一个概念,它事件本身的一个属性。 二.例子 去书店借一本书,同步就是我要亲自到书店,问老板有没有这本书,阻塞就是老板查询的时候(读写)我只能在那等着,老板找到书后把书交给我,这...
  • Linux异步机制

    千次阅读 2016-05-10 18:24:09
    什么是异步通知:很简单,一旦设备准备好,就主动通知应用程序,这种情况下应用程序就不需要查询设备状态, 特像硬件上常提的“中断的概念”。 比较准确的说法其实应该叫做“信号驱动的异步I/O”,信号在软件层次上...
  • 121-同步 IO 与异步 IO

    千次阅读 2017-03-28 14:48:40
    1. 引言至今为止,我们学习到的所有 IO 都是同步 IO。其主要特征是使用 read 或 ...我有点不太理解中文版本的 apue 把 select 和 poll 说成可以实现异步形式的通知是什么意思。参考图 1. 图 1 apue 中文版本有关异
  • Android中bindService一个异步的过程,什么意思呢?使用bindService无非想获得一个Binder服务的Proxy,但这个代理获取到的时机并非由bindService发起端控制,而是由Service端来控制,也就是说bindService之后,...
  • Android中bindService一个异步的过程,什么意思呢?使用bindService无非想获得一个Binder服务的Proxy,但这个代理获取到的时机并非由bindService发起端控制,而是由Service端来控制,也就是说bindService之后,...
  • Android中bindService一个异步的过程,什么意思呢? 使用bindService无非想获得一个Binder服务的Proxy,但这个代理获取到的时机并非由bindService发起端控制,而是由Service端来控制,也就是说bindService之后...
  • 异步异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,只要自己完成了整个任务就算完成了阻塞:阻塞调用指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他...
  • 非阻塞式通常对于I/O操作而言的,意思就是当你请求一个系统调用的时候,不管收到什么结果函数都会立即返回,而不让线程进入休眠状态以等待I/O操作的完成。相反阻塞式I/O方式在请求一个磁盘文件时会进入线程休眠...
  • 本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等 ...通过这两种系统的名字,估计你也能大概猜出来 IO 密集型系统是什么意思。 IO 密集型系统大部分时间都在执行 IO 操作,这个 IO.
  • 异步与同步模型最大的区别是,同步模型会阻塞线程等待资源,而异步模型不会阻塞线程,它是等资源准备好后,...通过这两种系统的名字,估计你也能大概猜出来IO密集型系统是什么意思。 IO密集型系统大部分时间都在执...
  • 什么是异步通知呢?异步通知意思就是,一旦设备就绪,则主动通知应用程序,应用程序 根本就不需要查询设备状态,类似于中断的概念,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号异步的,...
  • JavaIO学习笔记(五)

    2016-10-01 22:11:00
    异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知异步的特点就是通知什么是阻塞 所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有东西可...
  • Java IO模型总结

    千次阅读 2019-12-11 11:33:49
    异步指的用户进程触发IO操作后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知异步的特点就是通知)。 什么是阻塞? 所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有...
  • Java回调机制

    2021-02-03 11:08:28
    一、Java回调机制是什么意思 Java中的回调机制是什么意思呢?所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法。百度百科中对Java回调机制是这样解释的: 软件...
  • 100个问题搞定Java并发

    2021-06-08 08:54:20
    死锁、活锁和饥饿是什么意思? Java 中线程状态有哪些? Java中实现多线程的方法有哪些? JVM 中可以创建多少个线程? Java中有哪些方法可以终止线程运行? 如何理解 Java 的线程中断机制? 线程的等待(wait)和通知...
  • 注:面试过程中整理的学习资料,如有侵权联系我即刻删除。 目录 是否了解进程、线程、程序,以及这三者的区别 什么是虚拟内存 IO同步、异步、阻塞、非阻塞 ...死锁是什么意思? 死锁发生的...
  • 微信开发文档微信开发 notify_url:异步接收微信支付结果通知的回调地址,通知url必须为外... 一开始不懂说的是什么意思,后来经过测试可以使用PUT类型的接口传给商户服务器,服务器会接收到一些要用的信息做之后的处理,
  • 安装部署RabbitMQ

    2020-01-02 11:39:45
    一、什么是MQ 消息队列(Message Queue,简称MQ),从字面意思上看,本质个队列,FIFO先入先出,只不过队列中存放的内容message而已 作用:应用程序“对”应用程序的通信方法。 应用场景 主要解决异步处理、应用...
  • 缘起 笔者最近在看分布式事务的时候发现网上很多资料很零散,不够系统,看的云里雾里,比如在分布式事务...这么多关键词是什么意思?之间又有什么关系??本文旨在带你了解这些花里胡哨的叫法之间的关系,而不是需要...

空空如也

空空如也

1 2 3 4
收藏数 69
精华内容 27
关键字:

异步通知是什么意思