信号量sema
信号量是操作系统中最典型的用于同步与互斥的手段,信号量的值可以是0,1或者n。信号量与操作系统中经典概念PV操作相对应
Linux驱动中信号量的操作如下:
struct semaphore sem; // 定义信号量 void sema_init(struct semaphore *sem, int val); // 初始化信号量 void down(struct semaphore *sem); // 获取信号量,因为会导致休眠,因此不能在中断中使用 void down_interruptible(struct semaphore *sem); // 获取信号量,和down类似,也不能在中断中使用,使用该api可以被信号打断,信号也就是软件中断
信号量使用方法如下:
struct semaphore sem; /* 定义信号量 */ sema_init(&sem, 1); /* 初始化信号量 */ down(&sem); /* 申请信号量 */ /* 临界区 */ up(&sem); /* 释放信号量 */
信号量的使用测试demo:
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/kthread.h> #include <linux/delay.h> static struct task_struct *thread; static DECLARE_COMPLETION(completion); static DEFINE_SEMAPHORE(my_semaphore); // 线程函数 static int my_thread(void *data) { allow_signal(SIGKILL); // 允许接收SIGKILL信号 while (!kthread_should_stop()) { down(&my_semaphore); // 获取信号量 // 在这里执行需要同步的操作 printk(KERN_INFO "Thread running\n"); msleep(2000); up(&my_semaphore); // 释放信号量 if (signal_pending(current)) { break; // 如果收到信号则退出线程 } } complete_and_exit(&completion, 0); } static int __init my_init(void) { printk(KERN_INFO "Initializing module\n"); sema_init(&my_semaphore, 1); // 初始化信号量 thread = kthread_run(my_thread, NULL, "my_thread"); if (IS_ERR(thread)) { printk(KERN_ERR "Failed to create kernel thread\n"); return PTR_ERR(thread); } return 0; } static void __exit my_exit(void) { printk(KERN_INFO "Exiting module\n"); kthread_stop(thread); wait_for_completion(&completion); // 等待线程退出 } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL");
kthread_should_stop()是一个函数,用于检查内核线程是否应该停止执行并退出
signal_pending()是一个函数,用于检查当前进程是否有挂起的信号。在Linux内核编程中,进程可能会收到各种信号,例如SIGKILL、SIGINT等。signal_pending()函数可以用来检查当前进程是否有未处理的信号。
ps aux和ps -A的区别:
ps aux
- ps aux命令用于显示当前用户下的所有进程信息。
- a选项表示显示所有用户的进程,而不仅仅是当前用户。
- u选项表示以完整格式显示进程信息,包括用户、CPU占用率、内存占用率等。
ps -A
- ps -A命令也用于显示所有进程信息,但是不同于ps aux,它会显示所有用户的所有进程。
- -A选项表示显示所有进程,与-e选项效果相同。