网站别人做的收到方正侵权,wordpress链接提交表单,快餐网站模板,app推广方式有哪些目录 一、Linux的热插拔UDEV机制
二、守护进程
2.1 守护进程概念和基本特点#xff1a;
2.2 显示进程信息#xff1a;
2.3 守护进程和后台进程的区别#xff1a;
2.4 创建守护进程的步骤和守护进程的特征#xff1a;
2.4.1 创建守护进程的步骤#xff1a;
2.4.2 守…目录 一、Linux的热插拔UDEV机制
二、守护进程
2.1 守护进程概念和基本特点
2.2 显示进程信息
2.3 守护进程和后台进程的区别
2.4 创建守护进程的步骤和守护进程的特征
2.4.1 创建守护进程的步骤
2.4.2 守护进程的特征
2.5 创建守护进程函数daemon()原型和头文件
2.6 创建守护进程案例获取当前时间并写入到日志文件中
2.7 设置守护进程开机自启动
三、守护进程应用
3.1 判断某进程是否在运行
3.2 守护进程不让控制程序退出
3.3 把相关守护进程设置成开机自启动
四、UDEV的配置文件Udev的rules编写
4.1 UDEV的配置文件
4.2 UDEV规则的匹配键
五、自动挂载U盘
5.1 mount手动挂载U盘
5.2 UDEV自动挂载U盘的配置文件
5.3 实现自动挂载 一、Linux的热插拔UDEV机制
Linux 的热插拔机制主要通过 Udev用户空间设备来实现。Udev 是 Linux 系统中用于动态管理设备的设备管理器。以下是 Udev 实现热插拔的主要机制 设备事件监测 Udev 不断监听内核发出的事件以便检测设备的插入和拔出。内核通过 Netlink 通信机制向 Udev 发送设备事件。 规则匹配 当 Udev 检测到设备事件时它会根据预定义的规则规则文件来匹配事件中的设备信息。规则可以基于设备的各种属性、类型、路径等进行匹配。 规则文件 Udev 的规则文件通常存储在 /etc/udev/rules.d/ 目录下。这些规则文件定义了在特定条件下要执行的操作。规则文件的命名约定通常是 XX-name.rules其中 XX 是两位数字用于确定规则文件的加载顺序。 执行动作 当规则匹配成功时Udev 将执行相关的动作。动作可以包括创建设备节点、设置环境变量、执行脚本等。例如可以在设备插入时创建相应的设备节点、加载适当的驱动程序等。 设备节点管理 Udev 负责在 /dev 目录下创建或删除设备节点。这确保了用户和应用程序可以在一个标准位置找到设备节点而无需关心设备插入的确切时刻。 持久化设备节点 Udev 确保设备节点的持久性即使设备在重新启动后未连接也会分配相同的设备节点名称。这有助于确保应用程序可以依赖特定的设备节点。
总体而言Udev 通过规则匹配和执行动作的方式实现了对设备事件的监听和处理从而支持 Linux 系统的热插拔机制。这使得在系统运行时插入或拔出设备时系统能够动态地适应这些变化。 udev是一个设备管理工具udev以守护进程的形式运行通过侦听内核发出来的uevent来管理 /dev目录下的设备文件。通过侦听内核发出来的硬件数据事件在用户空间为这个硬件去创建对应代表该硬件的文件应用程序例如adb就可以通过该文件操作到硬件设备。 udev在用户空间运行而不在内核空间运行。它能够根据系统中的硬件设备的状态动态更新设备文件包括设备文件的创建删除等设备文件通常放在 /dev目录下。使用 udev后在 /dev目录下就只包含系统中真正存在的设备。
二、守护进程
守护进程Daemon Process是在计算机系统后台运行的一类进程它们通常在系统启动时启动不依赖于用户直接操作一直运行在后台不受用户登录或注销的影响。守护进程的存在主要是为了执行特定的系统任务或服务例如服务器、网络服务、定时任务等。
2.1 守护进程概念和基本特点 Linux Daemon守护进程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。守护进程的名称通常以d结尾 UDEV守护进程它能够根据系统中的硬件设备的状态动态更新设备文件包括设备文件的创建删除等。
基本特点 生存周期长[非必须]一般操作系统启动的时候就启动关闭的时候关闭。 守护进程和终端无关联也就是他们没有控制终端所以当控制终端退出也不会导致守护进程退出 守护进程是在后台运行不会占着终端终端可以执行其他命令 一个守护进程的父进程是init进程因为它真正的父进程在fork出子进程后就先于子进程exit退出了所以它是一个由init继承的孤儿进程
2.2 显示进程信息
linux操作系统本身是有很多的守护进程在默默执行维持着系统的日常活动。大概30-50个 ps -efj 是一个用于显示进程信息的命令。具体解释如下
ps -efj //显示进程信息ps 进程状态命令
-e 显示所有进程而不仅仅是与终端相关的进程
-f 以全格式显示
-j 以作业格式显示
在这个命令中-ef 是常用组合用于显示所有进程的详细信息。而 -j 则以作业格式显示包括作业控制的信息。 输出的各列含义如下 UID (User ID): 进程的用户标识。 PID (Process ID): 进程的唯一标识号。 PPID (Parent Process ID): 父进程的标识号。 PGID (Process Group ID): 进程组的标识号。 SID (Session ID): 会话的标识号。 TTY (Controlling Terminal): 控制终端。 TPGID (Foreground Group ID of the controlling terminal): 控制终端的前台进程组的标识号。 STAT (Process Status): 进程的状态如 R运行、S睡眠、Z僵尸等。 TIME (Cumulative CPU time): 进程执行的累计 CPU 时间。 COMMAND (Command with all its arguments): 进程的命令及其参数。
这个命令的输出显示了当前系统上所有进程的详细信息以及它们的层次结构和作业控制信息。
2.3 守护进程和后台进程的区别 守护进程和终端不挂钩后台进程能往终端上输出东西(和终端挂钩) 守护进程关闭终端时不受影响守护进程不会随着终端的退出而退出 守护进程Daemon Process和后台进程Background Process是两个不同的概念它们有以下区别 启动方式
守护进程 通常由系统启动独立于控制终端以在后台运行的方式启动。 后台进程 可以由用户手动将一个前台进程移至后台即使它最初是由用户启动的。 是否与终端关联
守护进程 通常不与任何控制终端关联因此它们不受终端关闭的影响。 后台进程 可以从终端启动并且可能受终端的影响。 执行环境
守护进程 在后台执行并且通常在系统引导时启动。它们通常在系统运行期间一直存在。 后台进程 通常是用户在前台启动的进程后来放到后台执行可能在终端关闭后继续运行。 继承环境
守护进程 通常会脱离终端会话重新设置文件权限改变工作目录等以确保独立于用户终端的环境。 后台进程 通常继承自其父进程通常是终端 Shell的环境。 用户交互性
守护进程 通常不与用户进行交互因为它们不关联于任何终端。 后台进程 在启动时可能与用户进行交互但放到后台后通常不再与用户直接交互。
总的来说守护进程是一种设计用于在系统后台一直运行的进程而后台进程是一种在终端启动后被放到后台执行的进程。
2.4 创建守护进程的步骤和守护进程的特征
2.4.1 创建守护进程的步骤 调用 fork 函数 创建一个子进程父进程退出子进程继续执行。 调用 setsid 函数 创建一个新的会话组使得子进程成为新的会话组长。 修改工作目录 为了防止卸载文件系统导致守护进程找不到文件通常需要更改工作目录。 重定向标准输入输出 将标准输入、输出、错误重定向到适当的文件。 关闭文件描述符 关闭不需要的文件描述符避免占用系统资源。 处理信号 捕获并处理一些信号如 SIGHUP。
创建和管理守护进程需要谨慎处理确保进程以安全和可靠的方式在后台运行。
2.4.2 守护进程的特征 后台运行 守护进程通常在后台运行不与任何终端关联不接受用户的直接输入。 脱离终端 守护进程通常会调用 fork 函数创建一个子进程并使得子进程成为新的会话组长从而脱离与终端的关联。 文件描述符 守护进程通常会关闭与终端相关的文件描述符以防止被终端关闭影响进程运行。 重定向标准输入输出 守护进程通常会将标准输入、输出、错误重定向到 /dev/null 或其他适当的文件以防止输出信息到终端。 权限 守护进程通常以超级用户或其他特定用户的身份运行以便执行需要特殊权限的任务。 信号处理 守护进程通常会捕获并处理一些特定的信号如 SIGHUP以便在配置文件更改或其他条件下重新加载配置。 周期性任务 守护进程通常执行一些周期性的任务如定时清理、日志轮转等。 示例 常见的守护进程包括 sshdSSH 服务器守护进程、httpdApache HTTP 服务器守护进程等
2.5 创建守护进程函数daemon()原型和头文件
/*Linux下 man daemon查看手册
*/
#include unistd.hint daemon(int nochdir, int noclose);int 函数返回值函数成功创建守护进程返回0失败返回-1int nochdir 参数用于指示是否改变守护进程的当前工作目录。如果 nochdir 为非零值守护进程的当前工作目录将保持不变为0时表示将当前目录更改至“/”int noclose 参数用于指示是否关闭所有的文件描述符。如果 noclose 为非零值守护进程将不会关闭标准输入、标准输出和标准错误。为0时表示将标准输入、标准输出、标准错误重定向至“/dev/null”
2.6 创建守护进程案例获取当前时间并写入到日志文件中
#include unistd.h // 包含unistd.h头文件提供对POSIX操作系统API的访问包括各种系统调用
#include signal.h // 包含信号处理函数的头文件
#include stdlib.h // 包含标准库函数的头文件
#include string.h // 包含字符串处理函数的头文件
#include fcntl.h // 包含文件控制选项的头文件
#include sys/stat.h // 包含文件状态信息的头文件
#include time.h // 包含时间处理函数的头文件
#include stdio.h // 包含标准输入输出函数的头文件
#include stdbool.h // 包含布尔类型定义的头文件//C 库函数 char *asctime(const struct tm *timeptr) 返回一个指向字符串的指针它代表了结构 struct timeptr 的日期和时间。
//C 库函数 struct tm *localtime(const time_t *timer) 使用 timer 的值来填充 tm 结构。timer 的值被分解为 tm 结构并用本地时区表示。
/*
struct tm {int tm_sec; 秒范围从 0 到 59int tm_min; 分范围从 0 到 59int tm_hour; 小时范围从 0 到 23int tm_mday; 一月中的第几天范围从 1 到 31int tm_mon; 月份范围从 0 到 11int tm_year; 自 1900 起的年数int tm_wday; 一周中的第几天范围从 0 到 6int tm_yday; 一年中的第几天范围从 0 到 365int tm_isdst; 夏令时
};
*/
static bool flag true;void handler(int sig) //信号处理函数
{printf(I got a signal %d\nIm quitting.\n, sig); //打印信息flag false; //设置flag为false退出循环
}int main()
{time_t t;int fd;//创建守护进程if (-1 daemon(0, 0)){ //创建守护进程第一个参数为0表示不创建控制终端第二个参数为0表示不创建进程组 printf(daemon error\n); //创建守护进程失败 exit(1); //退出程序}//设置信号处理函数struct sigaction act; //信号处理结构act.sa_handler handler; //信号处理函数sigemptyset(act.sa_mask); //清空信号集act.sa_flags 0; //不设置其他标志if (sigaction(SIGQUIT, act, NULL)){ //设置信号处理函数printf(sigaction error.\n);exit(0);}//进程工作内容while(flag){ //循环直到收到信号为止fd open(/home/orangepi/daemon.log, O_WRONLY | O_CREAT | O_APPEND, 0644); //打开日志文件if (fd -1){ //打开日志文件失败printf(open error\n); //打印错误信息exit(0); //退出程序}t time(0); //获取当前时间char *buf asctime(localtime(t)); //格式化时间字符串write(fd, buf, strlen(buf)); //写入日志文件close(fd); //关闭日志文件sleep(10); //睡眠10秒}return 0;
} 可见时间信息确实不断的追加打印到了这个文件并且只要不调用SIGQUIT哪怕关掉终端也不会结束运行只有系统关闭才会关闭
主要步骤 使用daemon函数创建守护进程。 设置信号处理函数处理SIGQUIT信号。 在循环中打开文件/home/orangepi/daemon.log将当前时间写入文件然后关闭文件然后休眠10秒。 当接收到SIGQUIT信号时程序会打印信息并退出。
请确保在运行此程序之前你有对/home/orangepi/目录的写入权限并且该目录下没有同名的文件。
2.7 设置守护进程开机自启动
守护进程一般是开机自启的实现这一点可以通过“sudo vi /etc/rc.local”然后添加守护进程的绝对路径来实现
sudo vi /etc/rc.local 我们重启开发板之后可以看到这个守护进程是开启自启动的 三、守护进程应用
实现功能要求抖音语音交互的程序一直保持运行防止应用程序崩溃意外
3.1 判断某进程是否在运行
#include stdio.h // 包含标准输入输出库的头文件
#include string.h // 包含字符串操作库的头文件int main()
{FILE *fp; // 定义文件指针char buffer[128] {\0}; // 定义缓冲区char *cmd ps -elf |grep douyinexe |grep -v grep; // 定义命令//FILE *popen(const char *command, const char *type);fp popen(cmd, r); // 使用 popen 函数执行命令并读取结果fgets(buffer, sizeof(buffer), fp); // 读取命令的输出if(strstr(buffer, douyinexe) ! NULL){ // 判断是否存在 douyinexe 进程printf(Douyin is running.\n);}else{printf(Douyin is not running.\n);}printf(buffer: %s\n,buffer); // 打印命令的输出pclose(fp); // 关闭命令的输出管道return 0;
} 3.2 守护进程不让控制程序退出
#include unistd.h // 包含unistd.h头文件提供对POSIX操作系统API的访问包括各种系统调用
#include signal.h // 包含信号处理函数的头文件
#include stdlib.h // 包含标准库函数的头文件
#include string.h // 包含字符串处理函数的头文件
#include fcntl.h // 包含文件控制选项的头文件
#include sys/stat.h // 包含文件状态信息的头文件
#include time.h // 包含时间处理函数的头文件
#include stdio.h // 包含标准输入输出函数的头文件
#include stdbool.h // 包含布尔类型定义的头文件static bool flag true;void handler(int sig) //信号处理函数
{printf(I got a signal %d\nIm quitting.\n, sig); //打印信息flag false; //设置flag为false退出循环
}int existMent() //判断是否存在抖音应用程序
{FILE *fp; // 定义文件指针char buffer[128] {\0}; // 定义缓冲区char *cmd ps -elf |grep douyinexe |grep -v grep; // 定义命令//FILE *popen(const char *command, const char *type);fp popen(cmd, r); // 使用 popen 函数执行命令并读取结果fgets(buffer, sizeof(buffer), fp); // 读取命令的输出if(strstr(buffer, douyinexe) ! NULL){ // 判断是否存在 douyinexe 进程return 0; // 存在返回0}else{return -1; // 不存在返回-1}printf(buffer: %s\n,buffer); // 打印命令的输出pclose(fp); // 关闭命令的输出管道
}int main()
{time_t t;int fd;//创建守护进程if (-1 daemon(0, 0)){ //创建守护进程第一个参数为0表示不创建控制终端第二个参数为0表示不创建进程组 printf(daemon error\n); //创建守护进程失败 exit(1); //退出程序}//设置信号处理函数struct sigaction act; //信号处理结构act.sa_handler handler; //信号处理函数sigemptyset(act.sa_mask); //清空信号集act.sa_flags 0; //不设置其他标志if (sigaction(SIGQUIT, act, NULL)){ //设置信号处理函数printf(sigaction error.\n);exit(0);}while(flag){ //循环直到收到信号为止if(existMent() -1){system(/home/orangepi/douyin/douyinexe /dev/ttyS5 ); // 启动抖音应用程序后台运行 sleep(2); // 等待2秒确保抖音应用程序启动成功 }}return 0;
} 3.3 把相关守护进程设置成开机自启动
设置douyinexe进程和守护进程douyindaemon为开启自启动
sudo vi /etc/rc.local 开机自启动绝对路径加程序名字 这样开机之后自动的运行刷抖音程序和守护进程程序不需要用指令来运行程序就可以直接语音刷抖音了。
四、UDEV的配置文件Udev的rules编写
4.1 UDEV的配置文件 规则文件是 udev 里最重要的部分默认是存放在 /etc/udev/rule.d/ 下。 所有的规则文件必须以 .rules为后缀名。
下面是一个简单的规则
KERNELsda, NAMEmy_root_disk, MODE0660 KERNEL 是匹配键NAME 和 MODE 是赋值键 这条规则的意思是如果有一个设备的内核名称为sda则该条件生效执行后面的赋值在 /dev 下产生一个名为my_root_disk 的设备文件并把设备文件的权限设为 0660。
同时在之前我们的语音刷抖音的项目当中手机接入香橙派不能识别的解决方案也是在udev的rules文件夹下创建规则文件“ 51-android.rules ”并写入以下规则
SUBSYSTEMusb, ENV{DEVTYPE}usb_device, MODE0666
那为什么这个规则要这么写呢
首先插入手机的USB设备对应的设备文件在/dev/bus/usb/002/006下 通过指令udevadm info --attribute-walk --name/dev/设备名字可以看到设备的详细信息此处的设备名字就是006 4.2 UDEV规则的匹配键 ACTION事件uevent的行为例如add添加设备、remove删除设备 KERNEL内核设备名称例如sdacdrom DEVPATH设备的 devpath 路径 SUBSYSTEM设备的子系统名称例如sda 的系统为 block BUS设备在 devpath 里的总线名称例如usb DRIVER设备在 devpath 的设备驱动名称例如ide-cdrom ID设备在 devpath 里的识别号 SYSFS{filename}设备的 devpath 路径下设备的属性文件 filename 里的内容 ENV{key}环境变量。在一条规则中可以设定最多五条环境变量的 匹配键 PROGRAM调用外部命令 RESULT外部命令 PROGRAM 的返回结果。
五、自动挂载U盘
把我的U盘拿出来插到香橙派的USB口 然后执行dmesg指令 可以看到Linux内核识别到了这个设备并显示为sda1
5.1 mount手动挂载U盘
sudo mount /dev/sda1 /mnt/
cd /mnt/ 我们可以看到U盘里面的文件和文件夹但是是乱码的乱码的原因是因为文件名是中文的但是这样很麻烦每次挂载U盘都得执行两个指令才可以挂载可以使用UDEV来实现自动挂载我们先把U盘弹出然后再使用UDEV机制自动挂载U盘 5.2 UDEV自动挂载U盘的配置文件
我们首先先执行下面一条指令来查看U盘的信息
udevadm info --attribute-walk --name/dev/sda1 ACTIONadd, SUBSYSTEMSusb, SUBSYSTEMblock, RUN{program}/bin/mkdir /media/%k ,RUN{program}/usr/bin/systemd-mount --no-block --collect $devnode /media/%k
这是一个udev规则通常用于在插入USB存储设备时自动创建挂载点并挂载设备。这个规则的含义如下 ACTIONadd规则只在添加设备时触发。 SUBSYSTEMSusb设备必须属于USB子系统。 SUBSYSTEMblock 设备必须是块设备。 RUN{program}/bin/mkdir /media/%k 当设备满足规则条件时运行命令创建 /media/ 目录下以设备名称%k命名的目录。 RUN{program}/usr/bin/systemd-mount --no-block --collect $devnode /media/%k 运行 systemd-mount 命令将设备挂载到之前创建的目录。
这个规则的效果是当插入一个USB块设备时udev将创建一个以设备名称为名字的目录例如如果设备名称是sdb1那么将创建 /media/sdb1 目录然后使用systemd-mount挂载设备。
请注意使用systemd-mount需要系统使用systemd init系统。此外一般情况下挂载点应该在/mnt/目录下而不是/media/因为/media/通常是由文件管理器等工具使用的默认挂载点。
cd /etc/udev/rules.d/
sudo vim my_usbpan.rules
sudo service udev restart 5.3 实现自动挂载
重新拔插U盘我们查看media文件夹是否挂载成功
cd /media 可以看到我们没有输入任何指令就可以访问U盘里面的文件实现了自动挂载。另外我们还可以使用tree指令来查看U盘文件
sudo apt-get install tree //安装tree指令 此时我们成功自动挂载U盘使用tree指令来查看U盘的文件如果我们现在拔掉U盘我们还会发现什么文件都没有了