守护进程编程、GDB调试以及外网连接树莓派
目录
- 一、什么是守护进程以及如何创建守护进程
- 1. 什么是守护进程?
- 2. 如何创建守护进程?
- 二、什么是GDB调试以及如何用GDB命令调试C程序
- 1. 什么是GDB?
- 2. 如何用GDB命令调试C程序?
- 三、外网访问树莓派
一、什么是守护进程以及如何创建守护进程
1. 什么是守护进程?
守护进程(Daemon Process)是一种特殊的后台进程,它独立于控制终端,并且周期性地执行某种任务或者等待处理特定事件。守护进程通常在系统启动时开始运行,直到系统关闭才结束,它们为系统提供各种服务,例如 Web 服务器、邮件服务器、日志记录等
2. 如何创建守护进程?
编程实现守护进程的主要过程:
- 创建子进程并终止父进程:通过 fork() 创建子进程,父进程退出,子进程继续运行。
- 创建新的会话:调用 setsid() 创建新的会话,使进程成为会话领导者,从而脱离原来的终端。
- 改变工作目录:通常将工作目录更改为根目录 /,避免因原工作目录被卸载而导致的进程终止。
- 重设文件权限掩码:调用 umask(0) 设置适当的文件权限掩码,确保守护进程创建的文件具有正确的权限。
- 关闭文件描述符:关闭所有不需要的文件描述符,避免资源泄漏。
- 重定向标准输入、输出和错误:将标准输入、输出和错误重定向到 /dev/null 或日志文件。
- 进入主循环:守护进程进入主循环,周期性地执行任务。
创建一个守护进程的三种方法:
由于阿里云服务器暂时无法登录,所以下面只展示在树莓派上的操作。
- 使用 nohup 命令
在阿里云服务器或树莓派上,可以使用以下命令创建守护进程:
nohup ./your_program > output.log 2>&1 &
nohup
使程序忽略 SIGHUP
信号,即使终端关闭,程序也会继续运行。
“>
” 将标准输出重定向到 output.log
文件。
2>&1
将标准错误也重定向到标准输出。
&
将程序放到后台运行。
- 使用 fork() 函数
以下是一个使用 fork() 函数创建守护进程的 C 程序示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>void daemonize() {pid_t pid = fork();if (pid < 0) {perror("fork");exit(EXIT_FAILURE);}if (pid > 0) {exit(EXIT_SUCCESS); // 父进程退出}// 创建新会话if (setsid() < 0) {perror("setsid");exit(EXIT_FAILURE);}// 改变工作目录if (chdir("/") < 0) {perror("chdir");exit(EXIT_FAILURE);}// 设置文件权限掩码umask(0);// 再次创建子进程并退出父进程pid = fork();if (pid < 0) {perror("fork");exit(EXIT_FAILURE);}if (pid > 0) {exit(EXIT_SUCCESS); // 父进程退出}// 关闭文件描述符close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);
}int main() {daemonize();while (1) {sleep(1); // 守护进程的主循环}return 0;
}
在阿里云服务器或树莓派上,编译并运行该程序:
gcc -o daemon_fork daemon_fork.c
./daemon_fork
- 使用 daemon() 函数
以下是一个使用 daemon() 函数创建守护进程的 C 程序示例:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>int main() {if (daemon(0, 0) == -1) {perror("daemon");return EXIT_FAILURE;}while (1) {sleep(1); // 守护进程的主循环}return 0;
}
在阿里云服务器或树莓派上,编译并运行该程序:
gcc -o daemon_daemon daemon_daemon.c
./daemon_daemon
二、什么是GDB调试以及如何用GDB命令调试C程序
1. 什么是GDB?
GDB 全称“GNU symbolic debugger”,从名称上不难看出,它诞生于 GNU 计划(同时诞生的还有 GCC、Emacs 等),是 Linux 下常用的程序调试器。发展至今,GDB 已经迭代了诸多个版本,当下的 GDB 支持调试多种编程语言编写的程序,包括 C、C++、Go、Objective-C、OpenCL、Ada 等。实际场景中,GDB 更常用来调试 C 和 C++ 程序。
总的来说,借助 GDB 调试器可以实现以下几个功能:
程序启动时,可以按照我们自定义的要求运行程序,例如设置参数和环境变量;
可使被调试程序在指定代码处暂停运行,并查看当前程序的运行状态(例如当前变量的值,函数的执行结果等),即支持断点调试;
程序执行过程中,可以改变某个变量的值,还可以改变代码的执行顺序,从而尝试修改程序中出现的逻辑错误。
2. 如何用GDB命令调试C程序?
1. 安装 GDB
在阿里云服务器或树莓派上,可以通过以下命令安装 GDB:
sudo apt-get update
sudo apt-get install gdb
安装完成后,可以通过运行 gdb --version
来验证是否安装成功
2. 编写和编译 C 程序
设计一个简单的 C 程序 example.c
:
#include <stdio.h>
int main() {int a = 5;int b = 10;int c = a + b;printf("The result is: %d\n", c);return 0;
}
为了能够使用 GDB 进行调试,需要在编译时加入 -g
选项,这样编译器会在生成的可执行文件中包含调试信息:
gcc -g -o example example.c
这将生成一个名为 example
的可执行文件
3. 使用 GDB 进行调试
有了带调试信息的可执行文件后,就可以使用 GDB 进行调试了。
启动 GDB
在终端中运行以下命令启动 GDB,并加载可执行文件:
gdb example
设置断点
在调试过程中,设置断点是非常重要的步骤。断点可以让程序在执行到某一行时暂停,方便查看和修改变量值。在 GDB 中,可以使用 break
命令设置断点,例如:
break main
这将设置一个断点在 main
函数的入口处。也可以在特定的行号或函数处设置断点,例如:
break example.c:10
运行程序
设置好断点后,可以使用 run
命令运行程序:
run
程序会在遇到断点时暂停,此时可以查看和修改变量的值
查看和修改变量
在程序暂停时,可以使用 print
命令查看变量的值,例如:
print a
如果需要修改变量的值,可以使用 set
命令,例如:
set var a = 20
继续执行程序
在查看和修改变量后,可以使用 continue 命令继续执行程序:
continue
三、外网访问树莓派
- 打开端口的防火墙
sudo ufw allow 9623
将9623设为反向代理的端口
- 设置SSH配置文件
GatewayPorts yes
然后重启 SSH 服务:
sudo systemctl restart ssh
- 通过putty程序ssh连接树莓派
- 登录树莓派后设置SSH反向代理
ssh -p 22 -qngfNTR [端口号]:localhost:22 [用户名]@[IP]
- 在阿里云服务器上查看监听端口
ss -ntl
有红框中的端口就说明服务器和树莓派成功连接
- 其他用户通过ssh命令连接到树莓派
ssh -p [你绑定的端口号] [树莓派用户]@云服务器地址
可以看见其他用户也能连接到树莓派上了