并发和竞态(实践篇)

1. complete.c 只是一个简单的字符驱动,但是我加进去了completion来同步读写操作

#include <linux/module.h>
#include <linux/init.h>

#include <linux/fs.h>     /* everything... */
#include <linux/types.h>  /* size_t */
#include <linux/completion.h>
#include <linux/cdev.h>

MODULE_AUTHOR("victorsummer");
MODULE_LICENSE("Dual BSD/GPL");

static int complete_major = 0;

DECLARE_COMPLETION(comp);

ssize_t complete_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
	wait_for_completion(&comp);
	return 0; 
}

ssize_t complete_write (struct file *filp, const char __user *buf, size_t count,
		loff_t *pos)
{
	complete(&comp);
	return count;
}


struct file_operations complete_fops = {
	.owner = THIS_MODULE,
	.read =  complete_read,
	.write = complete_write,
};

int complete_init(void)
{
	int result;
	dev_t dev = 0;
  
	struct cdev *complete_cdev = cdev_alloc();

	if (complete_major) {
		dev = MKDEV(complete_major, 0);
		result = register_chrdev_region(dev, 1, "completion");
	} else {
		result = alloc_chrdev_region(&dev, 0, 1, "completion");
		complete_major = MAJOR(dev);
	}
	if (result < 0) {
		return result;
	}

	cdev_init(complete_cdev, &complete_fops);
	complete_cdev->owner = THIS_MODULE;
	cdev_add(complete_cdev, dev, 1);

	return 0;
}

void complete_cleanup(void)
{
	dev_t devno = MKDEV(complete_major, 0);
	unregister_chrdev_region(devno, 1);
}

module_init(complete_init);
module_exit(complete_cleanup);

2. Makefile

ifneq ($(KERNELRELEASE),)
	obj-m := complete.o
else
	KERNELDIR ?= /usr/src/linux-headers-2.6.31-14-generic
	PWD := $(shell pwd)
default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif

3. completion_testr.c 调用read函数

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{
	int completion_fd;
	int code;	

	completion_fd = open("/dev/completion",O_RDONLY );
	if ((code=read(completion_fd, NULL, 0)) < 0) 
		printf("read err! code=%d /n",code);
        else   
		printf("read ok! code=%d /n",code);

	close(completion_fd);

        exit(0);
}

4. completion_testw.c 调用write函数

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{
	int completion_fd;
	int code;

	completion_fd = open("/dev/completion",O_WRONLY );

	if ((code=write(completion_fd, NULL, 0)) < 0 ) 
		printf("write error! code=%d /n",code);
	else   
		printf("write ok! code=%d /n",code);

	close(completion_fd);

        exit(0);
}

5. Makefile 使用make all编译读写程序

all : completion_testw.o completion_testr.o
		gcc -o completion_testw.o completion_testw.c
		gcc -o completion_testr.o completion_testr.c

 6. 开始测试啦

 

装载completion驱动

sudo insmod complete.ko

查看主设备号,假设为251

cat /proc/devices

建立设备节点

sudo mknod /dev/completion c 251 0

更改权限

sudo chgrp staff /dev/completion

sudo chmod 664 /dev/completion

 

实验1: 先运行completion_testw,再运行completion_testr

结果:  write ok! code=0

           read ok! code=0

 

实验2: 先运行两个completion_testr,再运行两个completion_testw

结果: completion_testr 1 阻塞

          completion_testr  2 阻塞

          completion_testw 1 打印 write ok! code=0

          同时 completion_testr 1 打印 read ok! code=0

          completion_testw 2 打印 write ok! code=0

          同时 completion_testr 2 打印 read ok! code=0



转自:http://blog.csdn.net/victorsummer/article/details/6094637
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值