Chinaunix首页 | 论坛 | 博客
  • 博客访问: 690666
  • 博文数量: 192
  • 博客积分: 1875
  • 博客等级: 上尉
  • 技术积分: 2177
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-23 23:21
个人简介

有时候,就是想窥视一下不知道的东东,因为好奇!

文章分类

全部博文(192)

文章存档

2024年(8)

2023年(3)

2019年(1)

2018年(1)

2017年(2)

2016年(69)

2015年(53)

2014年(14)

2013年(1)

2012年(5)

2011年(25)

2010年(9)

分类: LINUX

2011-02-23 21:45:28

completion

1.completion(补充?完成量?)

    一个执行路径等待另一个执行路径完成某事。可用于解决多处理器上发生的一种微妙的竞争条件。类似于线程同步中的条件变量,一个线程在pthread_cond_wait()上等待,另一个线程通过pthread_cond_signal()pthread_cond_broadcast()唤醒等待的一方。当然使用的环境是绝然不同的。


2.linux内核中的completion

定义:

struct completion comple;

初始化:

init_completion(&comple)

DECLARE_COMPLETION(comple)

等待

wait_for_completion(struct competion *comple)

唤醒

complete(struct completion *comple)  //唤醒一个等待的执行单元

complete_all(struct completion *comple) //唤醒全部等待同一个的执行单元

-----------------------------------------------------------------------------------------

简单例子一个
1. 环境
    
2. 代码
test.c

点击(此处)折叠或打开

  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/kernel.h>
  4. #include <linux/miscdevice.h>
  5. #include <linux/sched.h>
  6. #include <linux/completion.h>


  7. #include <linux/uaccess.h>
  8. #include <linux/fs.h>
  9. #include <linux/cdev.h>

  10. MODULE_LICENSE("GPL");
  11. MODULE_AUTHOR("zl");

  12. //char buffer[512];
  13. //struct cdev my_dev;
  14. //struct timer_list timer;
  15. //struct completion comple;
  16. DECLARE_COMPLETION(comple);

  17. ssize_t my_write(struct file *fp, const char __user *buf, size_t count, loff_t *off)
  18. {
  19.     complete(&comple);
  20.     //complete_all(&comple);
  21.     printk("[kernel: write] count = %ld.\n", count);
  22.     return count;
  23. }

  24. ssize_t my_read(struct file *fp, char __user *buf, size_t count, loff_t *off)
  25. {
  26.     printk("[kernel: read] goto sleep .\n");
  27.     //wait_for_completion_interruptible_timeout(&comple, jiffies + 10 * HZ);
  28.     //wait_for_completion_timeout(&comple, jiffies + 10 * HZ);
  29.     wait_for_completion(&comple);
  30.     printk("[kernel: read] wake up. count = %ld.\n", count);
  31.     return count;
  32. }

  33. int my_open(struct inode *no, struct file *fp)
  34. {
  35.     //fp->private_data = buffer;
  36.     //init_completion(&comple);
  37.     printk(" kernel: open.\n");
  38.     return 0;
  39. }

  40. int my_release(struct inode *no, struct file *fp)
  41. {
  42.     printk(" kernel: release.\n");
  43.     return 0;
  44. }

  45. struct file_operations my_ops = {
  46.     .open = my_open,
  47.     .release = my_release,
  48.     .read = my_read,
  49.     .write = my_write,
  50. };

  51. struct miscdevice mydevice = {
  52.     .minor = MISC_DYNAMIC_MINOR,
  53.     .name = "myDevice",
  54.     .fops = &my_ops,
  55. };

  56. int test_init(void)
  57. {
  58.     int ret = 0;
  59. #if 0
  60.     ret = register_chrdev_region(MKDEV(52,0), 5, "my dev");
  61.     if (ret) {
  62.         printk(" register device number failed.\n");
  63.         return ret;
  64.     }
  65. #endif
  66.     if(misc_register(&mydevice)) {
  67.         ret = -1;
  68.     }

  69.     return ret;
  70. }

  71. void test_exit(void)
  72. {
  73.     misc_deregister(&mydevice);
  74.     //unregister_chrdev_region(MKDEV(52,0), 5);    
  75. }

  76. module_init(test_init);
  77. module_exit(test_exit);
 Makefile

点击(此处)折叠或打开

  1. #KERNEL    = /home/zl/linux-2.6.30.4
  2. KERNEL    = /lib/modules/$(shell uname -r)/build


  3. default:
  4.     make -C $(KERNEL) M=$(shell pwd) modules

  5. clean:
  6.     make -C $(KERNEL) M=$(shell pwd) modules clean

  7. modules_install:
  8.     make -C $(KERNEL) M=$(shell pwd) modules_install INSTALL_MOD_PATH=/home/zl/tftpboot

  9. obj-m    += test.o
 read.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>

  5. int main(int argc, char **argv)
  6. {
  7.     int fd, ret;
  8.     char buf[512] = {0};

  9.     if (argc < 3 ) {
  10.         printf("Usage: %s \n", argv[0]);
  11.         return 0;
  12.     }

  13.     fd = open(argv[1], O_RDWR);
  14.     if (fd < 0) {
  15.         perror("open failed");
  16.         return 0;
  17.     }

  18.     ret = read(fd, buf, atoi(argv[2]));
  19.     buf[atoi(argv[2])] = 0;

  20.     printf("read %d Bytes: %s\n", ret, buf);
  21.     
  22.     close(fd);
  23.     return 0;
  24. }
write.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>

  5. int main(int argc, char **argv)
  6. {
  7.     int fd, ret;
  8.     char buf[10] = {0};

  9.     if (argc < 4 ) {
  10.         printf("Usage: %s \n", argv[0]);
  11.         return 0;
  12.     }

  13.     fd = open(argv[1], O_RDWR);
  14.     if (fd < 0) {
  15.         perror("open failed");
  16.         return 0;
  17.     }

  18.     ret = write(fd, argv[2], atoi(argv[3]));

  19.     printf("write %d Bytes.\n", ret);
  20.     
  21.     close(fd);
  22.     return 0;
  23. }
3. 编译及加载模块
    make clean;
    make;
    make write read
    sudo insmod test.ko;
  
 加载成功后有/dev/myDevice文件生成
    
    混杂字符设备的设备号及设备名,第一行就是。
    
4. 执行
    先执行read
    
   上面的read一直没以返回,直到后面的write执行成功

    后执行write(在另一个终端执行)
    
    执行完成后,前面的read执行完成返回


阅读(1164) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~