2023-05-18 08:06:14 阅读( 2457)
「阻塞与非阻塞定义」阻塞操作是指,在执行设备操作时,若不能获得资源,则进程挂起直到满足可操作的条件再进行操作。
阻塞和非阻塞阻塞的定义阻塞是指在执行设备操作时,如果不能获得资源,进程将被暂停,直到满足操作条件后才能操作。挂起的进程进入睡眠状态,并从调度程序的运行队列中移除,直到满足等待条件。
非阻塞操作的进程在无法操作设备时不会挂起。
"阻塞实例"
许多进程读写驱动程序中的全局变量,并使用阻塞机制来确保只有在一个进程写入该变量后,其他进程才能读取该变量。
#include #include #include #include #include #include
MODULE_LICENSE('GPL');
#define MAJOR_NUM 254
静态ssize_t全局变量_ read(struct file *,char *,size_t,
loff _ t *);静态ssize_t全局var _ write(struct file *、const char *、size_t、loff _ t *);
struct file _ operations全局var _ fops={ read:global var _ read,write: globalvar_write,};
Static intglobal _ var=0; Static structure semaphore sem static wait _ queue _ head _ t outq//defines the static int flag of the waiting queue head=0; //Blocking condition static int __init globalvar_init(void)
{ int retret=register _ chrdev(MAJOR _ NUM,' globalvar 'global var _ fops);如果(返回)
{ printk('globalvar register failure');} else { printk('globalvar register success');init_MUTEX(sem);init_waitqueue_head(outq);} return ret;} static void __exit globalvar_exit(void)
{ int retret=unregister _ chrdev(MAJOR _ NUM,' global var ');如果(返回)
{ printk('globalvar unregister failure');} else { printk('globalvar unregister success');}
静态ssize _ t全局变量_ read(struct file * filp,char *buf,size_t len,loff_t *off)
{//等待数据获取if(Wait _ event _ interruptible(outq,flag!=0))//让调用进程在这里进入挂起状态。
全///脚后的条件未从暂停状态中释放{ return-ERESTARTSYS;} if (down_interruptible(sem))
{ return-ERESTARTSYS;} flag=0;//阻塞条件在这里发生了变化,也就是说这个变量一次只能读取一次,除非再给这个//变量赋一个新值。
if (copy_to_user(buf, global_var, sizeof(int)))
{ up(sem);return - EFAULT;} up(sem);return sizeof(int);}
static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len,loff_t *off)
{ if (down_interruptible(sem))
{ return - ERESTARTSYS;} if (copy_from_user(global_var, buf, sizeof(int)))
{ up(sem);return - EFAULT;} up(sem);flag=1;//阻塞条件在这里发生改变,
意味着可以挂起的进程可以解禁了/*通知数据可获得前面调用驱动read函数的进程被调整到了挂起状态,只有当满足一个条件的时候才会从挂起状态摆脱。这个地方注意了,并没有一个机制自动的检测条件,
或者条件改变的时候,自动通知内核改变进程的状态。而是,我们需要调用函数去手动唤醒等待队列,队列会检测条件,如果条件满足,那么解禁进程,如果条件不满足,进程依然被封印。
*/wake_up_interruptible(outq);return sizeof(int);} module_init(globalvar_init);module_exit(globalvar_exit);
这里有一个问题,等待队列应该可能会有多个被封印的进程,在这种情况下:1. 后面的进程能否被前面的进程更早的解禁?
2. 每次通过函数试图唤醒队列的时候,队列对条件的检测机制是怎样的?是否一个一个的进程顺序的检测各自的条件吗?
用来对本驱动进行测试的参考应用程序为:「读程序」
#include #include #include #include main()
{ int fd, num;fd=open('/dev/globalvar', O_RDWR, S_IRUSR | S_IWUSR);if (fd !=- 1)
{ while (1)
{ read(fd, num, sizeof(int)); //程序将阻塞在此语句,除非有针对globalvar 的输入printf('The globalvar is %d\n',
num);//如果输入是0,则退出if (num==0)
{ close(fd);break;} else { printf('device open failure\n');}
「写程序」
#include #include #include #include main()
{ int fd, num;fd=open('/dev/globalvar', O_RDWR, S_IRUSR | S_IWUSR);if (fd !=- 1)
{ while (1)
{ printf('Please input the globalvar:\n');scanf('%d', num);write(fd, num, sizeof(int));//如果输入0,
退出if (num==0)
{ close(fd);break;} else { printf('device open failure\n');}
猜你喜欢
Guessyoulike