面试题答案
一键面试优化思路
- 合理规划信号使用:选择合适的信号,避免使用系统保留或可能在其他场景下干扰的信号。同时,不同子进程与父进程间的同步可以使用不同信号,降低信号竞争概率。
- 信号屏蔽与处理:
- 在父进程和子进程开始阶段,屏蔽相关同步信号,防止信号在进程未准备好时到达。
- 当进程准备好处理信号时,再解除屏蔽,确保信号不会丢失。
- 状态跟踪:父进程和子进程通过共享内存或文件等方式记录同步状态,使得各进程能够清楚知晓当前同步进展,避免因信号竞争导致的状态不一致。
- 使用信号集:利用信号集来管理多个信号,对信号进行统一的屏蔽、解除屏蔽和检测操作,提高代码的逻辑性和可读性。
可能用到的函数和机制
- 信号处理函数相关:
signal
函数:传统的设置信号处理函数的方式,但在多线程或复杂环境下可能有问题。sigaction
函数:更灵活强大,可设置信号处理函数、信号掩码、信号处理标志等。例如:
struct sigaction sa;
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGUSR1, &sa, NULL);
- 信号屏蔽相关:
sigprocmask
函数:用于设置、获取或修改当前进程的信号屏蔽字。可以通过它来屏蔽和解除对同步信号的屏蔽。例如,屏蔽信号:
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigprocmask(SIG_BLOCK, &set, NULL);
解除屏蔽:
sigprocmask(SIG_UNBLOCK, &set, NULL);
- 共享内存相关:
shmat
、shmget
、shmdt
等函数:用于创建、映射和分离共享内存段。通过共享内存,父进程和子进程可以共享同步状态信息。例如:
key_t key = ftok(".", 'a');
int shmid = shmget(key, sizeof(int), IPC_CREAT | 0666);
int *shared_status = (int *)shmat(shmid, NULL, 0);
// 使用共享状态
shmdt(shared_status);
- 文件操作相关:
- 可以使用标准的文件操作函数如
open
、write
、read
等,通过文件记录同步状态。不同进程通过读取和写入文件来更新和获取同步信息。但这种方式相对共享内存效率较低,适用于对效率要求不高的场景。
- 可以使用标准的文件操作函数如