我希望aio在读取操作完成时向我的程序发出信号,并且根据this page,这样的通知可以由内核发送的信号接收,或者通过启动运行用户函数的线程来接收。可以通过设置sigev_notify
的正确值来选择任一行为。
我尝试了一下,很快发现即使设置为通过信号接收通知,也会创建另一个线程。
(gdb) info threads
Id Target Id Frame
2 Thread 0x7ffff7ff9700 (LWP 6347) "xnotify" 0x00007ffff7147e50 in gettimeofday () from /lib64/libc.so.6
* 1 Thread 0x7ffff7fc3720 (LWP 6344) "xnotify" 0x0000000000401834 in update (this=0x7fffffffdc00)
该文档还指出:这些函数的实现可以使用内核中的支持(如果可用)或使用基于userlevel上的线程的实现来完成。 我想完全没有线程,这可能吗?
我检查了我的内核,看起来没问题:
qdii@localhost /home/qdii $ grep -i aio /usr/src/linux/.config
CONFIG_AIO=y
是否可以在没有任何(userland)线程的情况下运行aio(当然除了主线程之外)?
修改: 我深入研究了它。 librt似乎提供了一组aio函数:通过glibc源查看暴露的东西:在/rt/aio_read.c里面是一个函数存根:
int aio_read (struct aiocb *aiocbp)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (aio_read)
我在子目录sysdeps / pthread中找到了第一个相关的实现,它直接调用__aio_enqueue_request(..., LIO_READ)
,后者又创建了pthread。但是当我想知道为什么在这种情况下会有一个stup时,我想也许这个存根可以由linux内核本身实现,并且pthread实现将是某种回退代码。
通过我的/ usr / src / linux目录获取aio_read
给出了很多结果,我现在正试图理解。
答案 0 :(得分:1)
我发现实际上有两个非常不同的aio
库:一个是 glibc 的一部分,包含在librt中,并通过使用pthreads执行异步访问。另一个aio库实现了与第一个相同的接口,但它建立在linux内核本身之上,可以使用信号异步运行。