標籤:linux linux核心
#include<linux/fs.h>
#include<linux/sched.h>
#include<linux/kthread.h>
#include<linux/module.h>
#include<linux/delay.h>
#include<linux/seqlock.h>//順序鎖標頭檔
static int i=0,j=100;//一個線程從0開始加,一個線程從100開始加
struct task_struct *MyThread1=NULL;//線程1
struct task_struct *MyThread2=NULL;//線程2
static int myVar = 0;//定義變數
static int count = 0;
seqlock_t lock;//定義順序鎖
static void setMyVar(int input)//寫變數
{
write_seqlock(&lock);//加順序寫鎖
//臨界區
if(count)//count=1進入
{
printk("busy setMyVar\n");
}
count++;//conut=1
myVar = input;//寫變數,將input值賦值給myVar
printk("setMyVar is %d\n",myVar);//列印寫的變數值
write_sequnlock(&lock);//釋放順序寫鎖
count--;//count=0;
}
static int getMyVar(void)//讀變數
{
int res = 0;//用於讀取變數myVar的值
unsigned long seq;//順序鎖中的順序計數器
do
{
seq=read_seqbegin(&lock);//讀取順序號,如果是奇數,說明進行中寫操作,處理器就等待,如果不是奇數,就返回讀到的順序號
//臨界區
if(count)
{
printk("busy setMyVar\n");
}
count++;
res = myVar;//讀變數,將myVar變數值賦值給res
printk("getMyVar is %d\n",res);//列印讀取的變數res的值
}while(read_seqretry(&lock,seq));//檢測讀的資料有沒有效,如果順序號跟一開始的不一致,就返回1,說明修改了臨界區,需要重新讀資料
count--;//count=0;
return 0;
}
static int print1(void *data)//線程1列印函數
{
while(!kthread_should_stop())//判斷該線程是否停止,若線程未停止則進入
{
printk("this is thread1......\n");//提示這是線程1
getMyVar();//讀變數
setMyVar(i);//寫變數
ssleep(1);//沉睡1秒
i++;//i+1
}
return 0;
}
static int print2(void *data)//線程2列印函數
{
while(!kthread_should_stop())//判斷該線程是否停止,若線程未停止則進入
{
printk("this is thread2......\n");//提示這是線程2
getMyVar();//讀變數
setMyVar(j);//寫變數
ssleep(1);//沉睡1秒
j++;//j+1
}
return 0;
}
static int __init hello_init(void){//模組載入入口函數
seqlock_init(&lock);//順序鎖初始化
MyThread1 = kthread_run(print1,NULL,"mythread1");//建立線程1,名字是mythread1,調用的函數是print1函數
MyThread2 = kthread_run(print2,NULL,"mythread2");//建立線程2,名字是mythread2,調用的函數是print2函數
return 0;
}
static void __exit
hello_exit(void){//模組退出函數
if(MyThread1)//如果線程1還存在,那麼就停止該線程
{
printk("kthread1 stop....\n");//提示即將停止線程1
kthread_stop(MyThread1);//調用kthread_stop函數停止線程1
MyThread1=NULL;//將結構體指標MyThread1指向空
}
if(MyThread2)//如果線程2還存在,那麼就停止該線程
{
printk("kthread2 stop....\n");//提示即將停止線程2
kthread_stop(MyThread2);//調用kthread_stop函數停止線程2
MyThread2=NULL;//將結構體指標MyThread2指向空
}
}
module_init(hello_init);//模組載入
module_exit(hello_exit);//模組退出
MODULE_LICENSE("GPL");//模組許可證
MODULE_AUTHOR("Valerie Henson [email protected]");//模組作者資訊
MODULE_DESCRIPTION("\"rwlock\" minimal module");//模組描述
MODULE_VERSION("printk");//模組版本
linux順序鎖