阻塞型IO

Posted wszdezh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阻塞型IO相关的知识,希望对你有一定的参考价值。

技术分享图片

技术分享图片
  1 #include <linux/module.h>
  2 #include <linux/init.h>
  3 #include <linux/fs.h>
  4 #include <linux/cdev.h>
  5 
  6 #include <linux/wait.h>
  7 #include <linux/sched.h>
  8 
  9 #include <asm/uaccess.h>
 10 #include <linux/errno.h>
 11 
 12 #define DEBUG_SWITCH    1
 13 #if DEBUG_SWITCH
 14     #define P_DEBUG(fmt, args...)   printk("<1>" "<kernel>[%s]"fmt, __FUNCTION__, ##args)
 15 #else
 16     #define P_DEBUG(fmt, args...)   printk("<7>" "<kernel>[%s]"fmt, __FUNCTION__, ##args)
 17 #endif
 18 
 19 #define DEV_SIZE 100
 20 
 21 struct _test_t{
 22     char kbuf[DEV_SIZE];
 23     unsigned int major;
 24     unsigned int minor;
 25     unsigned int cur_size;
 26     dev_t devno;
 27     struct cdev test_cdev;
 28     wait_queue_head_t test_queue;    //1銆佸畾涔夌瓑寰呴槦鍒楀ご
 29 };
 30 
 31 int test_open(struct inode *node, struct file *filp)
 32 {
 33     struct _test_t *dev;
 34     dev = container_of(node->i_cdev, struct _test_t, test_cdev);
 35     filp->private_data = dev;
 36     return 0;
 37 }
 38 
 39 int test_close(struct inode *node, struct file *filp)
 40 {
 41     return 0;
 42 }
 43 
 44 ssize_t test_read(struct file *filp, char __user *buf, size_t count, loff_t *offset)
 45 {
 46     int ret;
 47     struct _test_t *dev = filp->private_data;
 48 
 49     /*浼戠湢*/
 50     P_DEBUG("read data.....\\n");
 51     if(wait_event_interruptible(dev->test_queue, dev->cur_size > 0))
 52         return - ERESTARTSYS;
 53 
 54     if (copy_to_user(buf, dev->kbuf, count)){
 55         ret = - EFAULT;
 56     }else{
 57         ret = count;
 58         dev->cur_size -= count;
 59         P_DEBUG("read %d bytes, cur_size:[%d]\\n", count, dev->cur_size);
 60     }
 61 
 62     return ret;        //杩斿洖瀹為檯鍐欏叆鐨勫瓧鑺傛暟鎴栭敊璇彿
 63 }
 64 
 65 ssize_t test_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset)
 66 {
 67     int ret;
 68     struct _test_t *dev = filp->private_data;
 69 
 70     if(copy_from_user(dev->kbuf, buf, count)){
 71         ret = - EFAULT;
 72     }else{
 73         ret = count;
 74         dev->cur_size += count;
 75         P_DEBUG("write %d bytes, cur_size:[%d]\\n", count, dev->cur_size);
 76         P_DEBUG("kbuf is [%s]\\n", dev->kbuf);
 77         /*鍞ら啋*/
 78         wake_up_interruptible(&dev->test_queue);
 79     }
 80 
 81     return ret;        //杩斿洖瀹為檯鍐欏叆鐨勫瓧鑺傛暟鎴栭敊璇彿
 82 }
 83 
 84 struct file_operations test_fops = {
 85     .open = test_open,
 86     .release = test_close,
 87     .write = test_write,
 88     .read = test_read,
 89 };
 90 
 91 struct _test_t my_dev;
 92 
 93 static int __init test_init(void)    //妯″潡鍒濆鍖栧嚱鏁?
 94 {
 95     int result = 0;
 96     my_dev.cur_size = 0;
 97     my_dev.major = 0;
 98     my_dev.minor = 0;
 99 
100     if(my_dev.major){                        
101         my_dev.devno = MKDEV(my_dev.major, my_dev.minor);
102         result = register_chrdev_region(my_dev.devno, 1, "test new driver");
103     }else{
104         result = alloc_chrdev_region(&my_dev.devno, my_dev.minor, 1, "test alloc diver");
105         my_dev.major = MAJOR(my_dev.devno);
106         my_dev.minor = MINOR(my_dev.devno);
107     }
108 
109     if(result < 0){
110         P_DEBUG("register devno errno!\\n");
111         goto err0;
112     }
113 
114     printk("major[%d] minor[%d]\\n", my_dev.major, my_dev.minor);
115 
116     cdev_init(&my_dev.test_cdev, &test_fops);
117     my_dev.test_cdev.owner = THIS_MODULE;
118     /*鍒濆鍖栫瓑寰呴槦鍒楀ご锛屾敞鎰忓嚱鏁拌皟鐢ㄧ殑浣嶇疆*/
119     init_waitqueue_head(&my_dev.test_queue);
120 
121     result = cdev_add(&my_dev.test_cdev, my_dev.devno, 1);
122     if(result < 0){
123         P_DEBUG("cdev_add errno!\\n");
124         goto err1;
125     }
126 
127     printk("hello kernel\\n");
128     return 0;
129 
130 err1:
131     unregister_chrdev_region(my_dev.devno, 1);
132 err0:
133     return result;
134 }
135 
136 static void __exit test_exit(void)        //妯″潡鍗歌浇鍑芥暟
137 {
138     cdev_del(&my_dev.test_cdev);
139     unregister_chrdev_region(my_dev.devno, 1);
140 
141     printk("good bye kernel\\n");
142 }
143 
144 module_init(test_init);
145 module_exit(test_exit);
146 
147 MODULE_LICENSE("GPL");
148 MODULE_AUTHOR("xoao bai");
149 MODULE_VERSION("v0.1");
test
技术分享图片
 1 #include <stdio.h>
 2 #include <sys/types.h>
 3 #include <sys/stat.h>
 4 #include <fcntl.h>
 5 
 6 int main(void)
 7 {
 8     char buf[20];
 9     int fd;
10     int ret;
11 
12     fd = open("/dev/test", O_RDWR);
13     if(fd < 0)
14     {
15         perror("open");
16         return -1;
17     }
18 
19     read(fd, buf, 10);
20     printf("<app>buf is [%s]\\n", buf);
21 
22     close(fd);
23     return 0;
24 }
app_read
技术分享图片
 1 #include <stdio.h>
 2 #include <sys/types.h>
 3 #include <sys/stat.h>
 4 #include <fcntl.h>
 5 
 6 int main(void)
 7 {
 8     char buf[20];
 9     int fd;
10     int ret;
11 
12     fd = open("/dev/test", O_RDWR);
13     if(fd < 0)
14     {
15         perror("open");
16         return -1;
17     }
18 
19     write(fd, "xiao bai", 10);
20 
21     close(fd);
22     return 0;
23 }
app_write
技术分享图片
验证:
[root: 1st]# insmod test.ko
major[253] minor[0]
hello kernel
[root: 1st]# mknod /dev/test c 253 0
[root: 1st]# ./app_read & //&表示后台运行app_read
[test_read]read data..... //因为没有数据,程序阻塞
[root: 1st]# ./app_write //再运行app_write
[test_write]write 10 bytes, cur_size:[10]
[test_write]kbuf is [xiao bai]
[test_read]read 10 bytes, cur_size:[0] //read继续执行
buf is [xiao bai] //打印读到的内容
[1] + Done ./app_read
[root: 1st]#
验证

http://blog.chinaunix.net/uid-25014876-id-60025.html

 

以上是关于阻塞型IO的主要内容,如果未能解决你的问题,请参考以下文章

Java 网络IO编程总结二(BIONIOAIO)

Java 网络IO编程总结二(BIONIOAIO)

5月2日 python学习总结 IO模型

Linux 下网络 IO 的多路复用

网络I/O模型

Mycat 网络通信模块源码