Character driver - synchronous mutex blocking

1. Atomic manipulation

Atomic operations are operations that are not interrupted by other code paths during execution.
Examples of common atomic operation functions:
atomic_t v = ATOMIC_INIT(0); //Define atomic variable v and initialize it to 0
atomic_read(atomic_t *v); //Return the value of atomic variable
void atomic_inc(atomic_t *v); //Atomic variable Increase by 1
void atomic_dec(atomic_t *v); //Atomic variable is decreased by 1
int atomic_dec_and_test(atomic_t *v); //Test whether it is 0 after the decrement operation, if it is 0, return true, otherwise return false.

2. Semaphore
Semaphore (semaphore) is a common method used to protect the critical section. Only the process that gets the semaphore can execute the critical section code.
When the semaphore cannot be obtained, the process enters the sleep waiting state.

Define
semaphore struct semaphore sem;
initialize semaphore
void sema_init (struct semaphore *sem, int val);
void init_MUTEX(struct semaphore *sem);//initialize to 0

static DECLARE_MUTEX(button_lock); //Define mutex

Get semaphore
void down(struct semaphore * sem);
int down_interruptible(struct semaphore * sem);
int down_trylock(struct semaphore * sem);
release semaphore
void up(struct semaphore * sem);

3. Blocking
Blocking
operation refers to suspending the process if resources cannot be obtained when performing device operations, and then performing the operation until the operable conditions are met.
The suspended process goes to sleep and is removed from the scheduler's run queue until the waiting condition is met.

Non-blocking operation The
process does not hang when it cannot perform device operations, it either gives up or keeps querying until it can operate.

fd = open("...", O_RDWR | O_NONBLOCK);

 

 Use atomic access to realize that the driver layer function is only called by one task (with the function of synchronizing threads):

First define an atomic variable with an initial value of 1:

Add judgment in the open function, this is an atomic operation:

If it is called for the first time, if will not be satisfied. The first time the self-decrement operation is 0, the self-decrement function returns true if it is 0, and the negation is false, which is not executed.

When the open function is called again by other processes at the same time, since the process called for the first time did not release resources, the self-decrement operation is -1, and the if condition is satisfied, first restore the state of the previous atomic variable, and then return the error code I am busy state, At this point the application may be prompted that the file cannot be opened.

The APP test procedure is as follows:

The terminal phenomenon is entered as follows:

Running the application in the background several times will prompt that it cannot be opened, but not the first time. At the same time, the keys are still valid.

 

Use the mutual exclusion mechanism to realize that the same application is called by only one process at the same time:

First define a mutex semaphore:

 

 在open函数中获取信号量:第一次来获取的时候,没有任何问题,在没有释放的情况下又一个线程来获取信号量的时候就需要等待第一次获取的线程释放了之后才可以。

在close函数中释放信号量:

应用程序后台运行并查看PID,此时为809:

 

 再次后台运行应用程序,并查看PID,此时为811:

 

 注意,这里的809,也就是第一次后台运行的时候,是处于S状态(可中断的睡眠状态),而在第一次没有释放信号量的时候,第二次后台运行应用程序显示的是D状态(不可中断状态,不是cpu不响应外部中断,而是该进程不响应异步信号)。

什么是不可中断状态呢?比如这里我们要kill掉这个进程,但由于811处于D状态,是不响应kill信号的。

 

现在我们把第一个进程809给kill掉(释放了信号量),此时会发现811变成了S状态,可以被异步信号触发了。

实验的时候意外发现,虽然刚才我们kill 811被拒绝了,但是当我kill 809之后,811被自动kill了,说明linux这里有保存操作的功能。

在互斥信号的时候不释放就再次打开不会提示can't open.而是进入休眠状态。

 

阻塞与非阻塞:

在open中判断应用程序是不是非阻塞的读取:

down_trylock如果无法获取信号量,立即返回。

应用程序,使用非阻塞的情况,阻塞情况前面的学习中已经实验过了:

终端显示:

没有按键下的时候,ret一直为-1

有按键的时候:

有按键时候,就不会返回-1.

but,是不是和我在看韦老师实验的时候一样,如同上图一样,明明有些地方有按键值,但是ret却是-1啊!!!

难道是驱动写出bug了?可韦老师的也是这样的现象啊。

Answer:

bug是有,但不是这里的非阻塞驱动,是我的按键程序,在按键按下之后是一个值,松开之后是另外一个,在没有按键的时候,应该将这个按键值清零才对。

 更改read驱动函数如下:

 

 这样更改了之后,没有按键的时候就是0键值,ret为-1,有按键的时候就是返回键值,ret为1.

进步是有的,能够发现老师代码bug了。每天给自己一点鼓励,前路漫漫其修远,吾将上下而求索。

韦老师也说了更加深入的知识点需要看更多的书籍,这里只是简单的入门介绍。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325109341&siteId=291194637