Linux内核-内核层互斥锁实现

内核层代码实现

#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/delay.h>

#define DEVNAME	"mutex"

/*
 	产生竞争的全局变量,用于表示读写的满足条件,读一次
	更新成false表示空,写一次更新成true,表示满,只有可
	读写时方可读写。
 */
static int is_full = false;

static struct mutex mutex;

ssize_t 
demo_read (struct file *filp, char __user *buf, size_t cnt, loff_t *fpos)
{
	int ret;

	if (cnt == 0) {
		return cnt;
	}	

	/*获得互斥锁*/
	mutex_lock(&mutex);

	if (is_full == true) {
		printk("[kernel]: reading...\n");
		mdelay(50);
		is_full = false;
		ret = cnt;
		printk("[kernel]: read done.\n");
	} else {
		ret = -EIO;
	}

	/*释放互斥锁*/
	mutex_unlock(&mutex);

	return ret;
}

ssize_t 
demo_write (struct file *filp, const char __user *buf, size_t cnt, loff_t *fpos)
{
	int ret;

	if (cnt == 0) {
		return cnt;
	}

	/*获得互斥锁*/
	mutex_lock(&mutex);
	if (is_full == false) {

		printk("[kernel]: writing...\n");
		mdelay(50);
		is_full = true;
		printk("[kernel.]: write done.\n");

		ret = cnt;
	} else {
		ret = -EIO;
	}
	/*释放互斥锁*/
	mutex_unlock(&mutex);

	return ret;
}
/*
第一个指针指向自己
实现read write 的驱动函数,为上层的read write 服务
*/
static struct file_operations fops = {
	.owner		=  	THIS_MODULE,
//	.open		=	demo_open,
	.read		=	demo_read,
	.write		=	demo_write,
//	.release	= 	demo_release,	
};
/* 自动生成一个主设备号为10  次设备号为系统自动分配
设备名字为DEVANAME的设备文件
并且关联操作函数集*/
static struct miscdevice misc = {
	.minor	= 	MISC_DYNAMIC_MINOR,
	.name	=	DEVNAME,
	.fops	=	&fops,
};

static int demo_init(void)   //驱动函数模块的入口
{
	int ret;

	/*初始化互斥锁*/
	mutex_init(&mutex);

	ret = misc_register(&misc);  注册一个混杂设备驱动
	if (ret < 0) {
		return ret;
	}

	return 0;
}

module_init(demo_init);

static void demo_exit(void)  //驱动的出口
{
	misc_deregister(&misc);  //销毁注册过的混杂设备驱动

	printk("goodbye...\n");
}

module_exit(demo_exit);

MODULE_LICENSE("GPL");  //发表为GPL的声明  必须写

MODULE_VERSION("2018-09-30");
MODULE_AUTHOR("Hebowen");
MODULE_DESCRIPTION("a simple demo for module");

用户上层app编写 每次只有1个进程写成功或者读成功,实现了互斥

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>

#define N 98 

#define SZ 512

/*
 	./a.out /dev/semaphore  r/w
 */
int main(int argc, char **argv)
{
	int fd;
	int ret;
	int i;
	pid_t pid[N];
	char buf[SZ];

	if (argc != 3) {
		fprintf(stderr, "Usage: %s devicefile r/w\n", argv[0]);
		exit(1);
	}

	fd = open(argv[1], O_RDWR | O_NDELAY);
	assert(fd > 0);

	for (i = 0; i < N; i++) { 
		if ((pid[i] = fork()) < 0) {
			perror("fork");
			exit(1);
		}

		if (pid[i] == 0) {
			if (!strncmp(argv[2], "r", 1)) {
				ret = read(fd, buf, SZ);
				assert(ret == SZ);
				printf("ret = %d\n", ret);
				printf("[app%d]: read %dBytes ok!\n", 
						getpid(), ret);
				close(fd);
				return;	
			} else if (!strncmp(argv[2], "w", 1)) {
				ret = write(fd, buf, SZ);
				assert(ret == SZ);
				printf("[app%d]: write %dBytes ok!\n", 
						getpid(), ret);
				close(fd);
				return;	
			}			
		}
	}

	for (i = 0; i < N; i++) {
		waitpid(pid[i], NULL, 0);
	}

	close(fd);

	return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值