信号量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选项效果相同。
posted @ 2024-03-25 20:59  lethe1203  阅读(12)  评论(0编辑  收藏  举报