有名管道
1. 创建有名管道
-
函数原型:
int mkfifo(const char *pathname, mode_t mode);
-
描述: 该函数用于创建一个有名管道(FIFO)。
pathname
是你想要创建的管道的路径,mode
是设置管道权限的标志(如读写权限)。成功时返回 0,失败时返回 -1 并设置errno
。
2. 打开有名管道
-
函数原型:
int open(const char *pathname, int flags);
-
描述: 该函数用于打开有名管道。
pathname
是有名管道的路径,flags
指定打开文件的模式(如只读、只写、读写等)。成功时返回文件描述符,失败时返回 -1 并设置errno
。
3. 读数据
-
函数原型:
ssize_t read(int fd, void *buf, size_t count);
-
描述: 该函数从有名管道中读取数据。
fd
是文件描述符,buf
是用来存储读取数据的缓冲区,count
是要读取的字节数。成功时返回实际读取的字节数,失败时返回 -1 并设置errno
。如果有名管道的另一端已关闭,返回 0 表示到达文件末尾。
4. 写数据
-
函数原型:
ssize_t write(int fd, const void *buf, size_t count);
-
描述: 该函数向有名管道写入数据。
fd
是文件描述符,buf
是包含要写入数据的缓冲区,count
是要写入的字节数。成功时返回实际写入的字节数,失败时返回 -1 并设置errno
。
5. 关闭有名管道
-
函数原型:
int close(int fd);
-
描述: 该函数用于关闭文件描述符。
fd
是要关闭的文件描述符。成功时返回 0,失败时返回 -1 并设置errno
。
6. 删除有名管道
-
函数原型:
int unlink(const char *pathname);
-
描述: 该函数用于删除有名管道文件。
pathname
是要删除的有名管道的路径。成功时返回 0,失败时返回 -1 并设置errno
。
有名管道的主要特点:
1. 持久性
- 有名管道在文件系统中存在,直到被明确删除。与匿名管道不同,有名管道的存在不依赖于进程的生命周期,因此它们可以在不同的进程和会话之间共享。
2. 全双工通信
- 虽然单个有名管道是半双工的(即数据只能单向流动),但可以通过创建两个有名管道实现全双工通信:一个用于发送数据,另一个用于接收数据。
3. 进程间通信
- 有名管道允许不同进程间的通信,而不仅限于父子进程。任何可以访问有名管道的进程都可以进行读写操作,从而实现进程间的数据交换。
4. 阻塞特性
- 读操作阻塞: 如果管道中没有数据,读取操作会阻塞,直到有数据可读。
- 写操作阻塞: 如果管道的读端没有被打开,写入操作会阻塞,直到有读端打开以读取数据。
5. 数据流
- 数据在有名管道中的流动是按顺序的,写入的数据会按照写入的顺序被读取。
6. 同步和互斥
- 由于有名管道的阻塞特性,它本身提供了一种简单的同步机制。例如,读操作的阻塞可以确保数据被写入后再进行读取。
7. 权限和安全
- 有名管道的权限可以通过
chmod
命令设置,允许用户控制哪些进程可以访问管道。这提供了一定的安全控制,但需注意管道的权限设置以防止未授权访问。
8. 文件系统接口
- 有名管道在文件系统中以特殊文件的形式存在,允许使用标准的文件操作命令(如
ls
,cat
,rm
等)进行管理。这使得有名管道在文件系统中易于识别和操作。
9. 跨会话和跨用户
- 由于有名管道存在于文件系统中,它们可以被不同用户和不同会话的进程访问,只要它们有适当的权限。
10. 非适合长时间存储
- 有名管道主要用于短期的数据传输,不适合存储长时间的数据。数据在有名管道中的生命周期通常与进程的通信需求相关。
signal
1. signal()
-
函数原型:
void (*signal(int signum, void (*handler)(int)))(int);
-
描述: 设置信号的处理程序。
signum
是要处理的信号的编号,handler
是信号处理函数的指针。返回值是旧的信号处理函数的指针。 -
用法: 用于设置特定信号的处理函数。当指定的信号发生时,操作系统会调用设定的处理函数。
2. sigaction()
-
函数原型:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
-
描述: 用于更复杂的信号处理设置。
signum
是信号的编号,act
是一个sigaction
结构体的指针,用于指定新的信号处理行为,oldact
是一个指向sigaction
结构体的指针,用于保存旧的信号处理行为。 -
用法: 允许设置信号处理程序以及附加选项,如信号阻塞或修改信号处理的标志。
3. sigemptyset()
-
函数原型:
int sigemptyset(sigset_t *set);
-
描述: 初始化信号集为空。
set
是指向sigset_t
类型的信号集的指针。 -
用法: 用于创建一个不包含任何信号的空信号集。这在设置信号屏蔽字或处理信号时非常有用。
4. sigaddset()
-
函数原型:
int sigaddset(sigset_t *set, int signum);
-
描述: 将指定的信号添加到信号集中。
set
是信号集,signum
是要添加的信号的编号。 -
用法: 用于将信号添加到信号集中。
5. sigdelset()
-
函数原型:
int sigdelset(sigset_t *set, int signum);
-
描述: 从信号集中删除指定的信号。
set
是信号集,signum
是要删除的信号的编号。 -
用法: 用于从信号集中移除某个信号。
6. sigismember()
-
函数原型:
int sigismember(const sigset_t *set, int signum);
-
描述: 检查信号是否在信号集中。
set
是信号集,signum
是要检查的信号的编号。返回值为非零表示信号在集合中,零表示不在集合中。 -
用法: 用于判断信号是否属于指定的信号集。
7. sigprocmask()
-
函数原型:
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
-
描述: 改变进程的信号屏蔽字。
how
指定如何修改当前信号屏蔽字(如SIG_BLOCK
,SIG_UNBLOCK
,SIG_SETMASK
),set
是新的信号集,oldset
用来保存之前的信号集。 -
用法: 用于阻塞、解除阻塞或设置进程的信号屏蔽字。
8. kill()
-
函数原型:
int kill(pid_t pid, int sig);
-
描述: 向指定进程发送信号。
pid
是进程的 ID,sig
是要发送的信号的编号。 -
用法: 用于向进程发送信号,例如终止进程或通知进程某个事件发生
信号类型
-
SIGHUP
(1): 挂起信号- 描述: 通常表示终端的挂起,或者控制终端的连接断开。通常用于重新加载配置文件。
-
SIGINT
(2): 中断信号- 描述: 通常由用户通过按
Ctrl+C
发送,用于中断当前进程。
- 描述: 通常由用户通过按
-
SIGQUIT
(3): 退出信号- 描述: 通常由用户通过按
Ctrl+\
发送,导致进程终止并生成核心转储(core dump)。
- 描述: 通常由用户通过按
-
SIGILL
(4): 非法指令信号- 描述: 进程尝试执行非法的处理器指令。
-
SIGTRAP
(5): 跟踪陷阱信号- 描述: 用于调试目的,例如断点。
-
SIGABRT
(6): 异常终止信号- 描述: 由
abort()
函数发送,通常表示进程因内部错误而终止。
- 描述: 由
-
SIGBUS
(7): 总线错误信号- 描述: 进程尝试访问无效地址或进行非法内存访问。
-
SIGFPE
(8): 浮点异常信号- 描述: 进程进行浮点运算时发生错误(如除零错误)。
-
SIGKILL
(9): 强制终止信号- 描述: 强制终止进程,不能被捕获、阻塞或忽略。
-
SIGUSR1
(10): 用户定义信号1- 描述: 用户可以自定义使用的信号。
-
SIGSEGV
(11): 段错误信号- 描述: 进程试图访问无效的内存段。
-
SIGUSR2
(12): 用户定义信号2- 描述: 用户可以自定义使用的信号。
-
SIGPIPE
(13): 管道破裂信号- 描述: 进程向一个已经关闭的管道写数据时发送。
-
SIGALRM
(14): 定时器到期信号- 描述: 由
alarm()
函数设置的定时器到期时发送。
- 描述: 由
-
SIGTERM
(15): 终止信号- 描述: 请求进程终止,进程可以捕获并进行清理操作。
-
SIGSTKFLT
(16): 堆栈故障信号- 描述: 发生堆栈溢出时发送。
-
SIGCHLD
(17): 子进程状态改变信号- 描述: 子进程状态发生变化时发送给父进程。
-
SIGCONT
(18): 继续执行信号- 描述: 恢复被停止的进程的执行。
-
SIGSTOP
(19): 停止信号- 描述: 停止进程执行,不能被捕获、阻塞或忽略。
-
SIGTSTP
(20): 终端停止信号- 描述: 通常由用户通过按
Ctrl+Z
发送,暂停当前进程的执行。
- 描述: 通常由用户通过按
-
SIGTTIN
(21): 终端输入信号- 描述: 进程在后台尝试读取终端时发送。
-
SIGTTOU
(22): 终端输出信号- 描述: 进程在后台尝试写入终端时发送。
-
SIGURG
(23): 紧急数据到达信号- 描述: 通知进程有紧急数据到达。
-
SIGXCPU
(24): CPU 时间限制超标信号- 描述: 进程使用的 CPU 时间超出设定限制。
-
SIGXFSZ
(25): 文件大小限制超标信号- 描述: 进程尝试写入超过文件大小限制的文件时发送。
-
SIGVTALRM
(26): 虚拟定时器到期信号- 描述: 虚拟计时器到期时发送。
-
SIGPROF
(27): 统计定时器到期信号- 描述: 统计定时器到期时发送。
-
SIGWINCH
(28): 窗口大小改变信号- 描述: 终端窗口大小改变时发送。
-
SIGIO
(29): I/O 操作信号- 描述: I/O 操作完成时发送。
-
SIGPWR
(30): 电源恢复信号- 描述: 电源恢复时发送。
-
SIGSYS
(31): 不合法系统调用信号- 描述: 进程执行非法的系统调用时发送
设置信号处理函数
可以使用 signal()
或 sigaction()
函数设置信号处理函数。
#include <stdio.h>
#include <signal.h>
void signal_handler(int signal) {
printf("Received signal %d\n", signal);
}
int main() {
signal(SIGINT, signal_handler); // 设置信号处理函数
while (1) {
// 主循环
}
return 0;
}
使用 sigaction()
设置信号处理函数
#include <stdio.h>
#include <signal.h>
void signal_handler(int signal) {
printf("Received signal %d\n", signal);
}
int main() {
struct sigaction sa;
sa.sa_handler = signal_handler;
sa.sa_flags = 0; // 默认值
sigemptyset(&sa.sa_mask); // 不屏蔽任何信号
sigaction(SIGINT, &sa, NULL); // 设置信号处理函数
while (1) {
// 主循环
}
return 0;
}
标签:函数,int,signal,管道,有名,信号,进程,描述
From: https://blog.csdn.net/a8687216/article/details/141285517