定义在头文件linux/mutex.h中;
互斥体(mutex)是Linux系统提供的另外一种互斥机制;在Linux内核中是真实存在的;
1).定义互斥体
struct mutex my_mutex; //定义互斥体
mutex_init(&my_mutex); //初始化互斥体
2).获取和释放互斥体:
void mutex_lock(struct mutex* lock); //获取互斥体,不可被信号中断
void mutex_lock_interruptible(struct mutex* lock); //获取互斥体,可被信号打断
int mutex_trylock(struct mutex* lock); //尝试获取互斥体
void mutex_unlock(struct mutex* lock); //释放互斥体
3).其它函数:
int mutex_is_locked(struct mutex* lock):
该函数检查互斥锁lock是否处于锁定状态;返回1,表示已锁定;返回0,表示未锁定;
int mutex_lock_interruptible(struct mutex* lock); //该函数可被信号打断
int mutex_lock_killable(struct mutex* lock); //该函数可被kill信号打断
4).互斥体的使用模式:
struct mutex my_mutex; //定义互斥体
mutex_init(&my_mutex); //初始化互斥体
mutex_lock(&my_mutex); //获取互斥体
...... //临界区代码
mutex_unlock(&my_mutex); //释放互斥体
例子:
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
//这三个头文件与内核线程的使用有关;
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/err.h>
//互斥量相关
#include <linux/mutex.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("*************");
MODULE_VERSION("2.6.35.000");
static int sleep_time = (1*10*HZ);
static int shared_res = 0;
//STEP1:定义互斥量
struct mutex my_mutex;
//STEP5:实现线程函数
static int thread_process1(void* param)
{
//int val = 0, ret = 0;
while(1)
{
set_current_state(TASK_UNINTERRUPTIBLE);
if(kthread_should_stop())
{
printk("kernel thread '%s' should stop;file:%s;line:%d\n", __FUNCTION__, __FILE__, __LINE__);
break;
}
//STEP3:对临界区加锁
mutex_lock(&my_mutex);
shared_res++;
//STEP4:对临界区解锁
mutex_unlock(&my_mutex);
mdelay(sleep_time);
}
return 12;
};
static int thread_process2(void* param)
{
//int val = 0, ret = 0;
while(1)
{
set_current_state(TASK_UNINTERRUPTIBLE);
if(kthread_should_stop())
{
printk("kernel thread '%s' should stop;file:%s;line:%d\n", __FUNCTION__, __FILE__, __LINE__);
break;
}
//STEP3:对临界区加锁
mutex_lock(&my_mutex);
shared_res++;
//STEP4:对临界区解锁
mutex_unlock(&my_mutex);
msleep(sleep_time);
}
return 34;
};
static int thread_process3(void* param)
{
int val = 0;//, ret = 0;
while(1)
{
set_current_state(TASK_UNINTERRUPTIBLE);
if(kthread_should_stop())
{
printk("kernel thread '%s' should stop;file:%s;line:%d\n", __FUNCTION__, __FILE__, __LINE__);
break;
}
//STEP3:对临界区加锁
mutex_lock(&my_mutex);
val = shared_res;
printk("%s: shared resource = %d;\n%s", __FUNCTION__, val, ((val % 3) ? "" : "\n"));
//STEP4:对临界区解锁
mutex_unlock(&my_mutex);
msleep(sleep_time);
}
return 56;
};
static int thread_process4(void* param)
{
int val = 0;//, ret = 0;
while(1)
{
set_current_state(TASK_UNINTERRUPTIBLE);
if(kthread_should_stop())
{
printk("kernel thread '%s' should stop;file:%s;line:%d\n", __FUNCTION__, __FILE__, __LINE__);
break;
}
//STEP3:对临界区加锁
mutex_lock(&my_mutex);
val = shared_res;
printk("%s: shared resource = %d;\n%s", __FUNCTION__, val, ((val % 3) ? "" : "\n"));
//STEP4:对临界区解锁
mutex_unlock(&my_mutex);
msleep(sleep_time);
}
return 78;
};
static struct task_struct* my_thread1 = NULL;
static struct task_struct* my_thread2 = NULL;
static struct task_struct* my_thread3 = NULL;
static struct task_struct* my_thread4 = NULL;
static int __init study_init(void)
{
int err = 0;
printk("%s\n", __PRETTY_FUNCTION__);
//STEP2:初始化互斥量
mutex_init(&my_mutex);
printk("init mutex ok\n");
my_thread1 = kthread_create(thread_process1, NULL, "my_thread1");
if(IS_ERR(my_thread1))
{
err = PTR_ERR(my_thread1);
my_thread1 = NULL;
printk(KERN_ERR "unable to start kernel thread1:%d\n", err);
return err;
}
my_thread2 = kthread_create(thread_process2, NULL, "my_thread2");
if(IS_ERR(my_thread2))
{
err = PTR_ERR(my_thread2);
my_thread2 = NULL;
printk(KERN_ERR "unable to start kernel thread2:%d\n", err);
return err;
}
my_thread3 = kthread_create(thread_process3, NULL, "my_thread3");
if(IS_ERR(my_thread3))
{
err = PTR_ERR(my_thread3);
my_thread3 = NULL;
printk(KERN_ERR "unable to start kernel thread3:%d\n", err);
return err;
}
my_thread4 = kthread_create(thread_process4, NULL, "my_thread4");
if(IS_ERR(my_thread4))
{
err = PTR_ERR(my_thread4);
my_thread4 = NULL;
printk(KERN_ERR "unable to start kernel thread4:%d\n", err);
return err;
}
wake_up_process(my_thread1);
wake_up_process(my_thread2);
wake_up_process(my_thread3);
wake_up_process(my_thread4);
printk("%s:all kernel thread start;\n", __FUNCTION__);
return 0;
}
static void __exit study_exit(void)
{
int ret = -1;
printk("%s\n",__PRETTY_FUNCTION__);
if(my_thread1)
{
ret = kthread_stop(my_thread1);
my_thread1 = NULL;
printk("kernel thread1 stop,exit code is %d;\n",ret);
}
if(my_thread2)
{
ret = kthread_stop(my_thread2);
my_thread2 = NULL;
printk("kernel thread2 stop,exit code is %d;\n",ret);
}
if(my_thread3)
{
ret = kthread_stop(my_thread3);
my_thread3 = NULL;
printk("kernel thread3 stop,exit code is %d;\n",ret);
}
if(my_thread4)
{
ret = kthread_stop(my_thread4);
my_thread4 = NULL;
printk("kernel thread4 stop,exit code is %d;\n",ret);
}
printk("%s:all kernel thread stop;\n", __FUNCTION__);
}
module_init(study_init);
module_exit(study_exit);