1.使用消息队列完成两个进程之间相互通信
2.信号通信相关代码的重新实现
(1)signal函数的实例
#include <head.h>//定义信号处理函数
void handler(int signum)
{if(signum == SIGINT) //表明要处理2号信号{printf("用户按下了ctrl + c键\n");}if(signum == SIGTSTP) //处理暂停信号{printf("用户按下了ctrl + z键\n");}
}/****************************主程序********************/
int main(int argc, const char *argv[])
{/*将SIGINT信号忽略if(signal(SIGINT, SIG_IGN) == SIG_ERR){perror("signal error");return -1;}*//*将SIGINT信号默认处理if(signal(SIGINT, SIG_DFL) == SIG_ERR){perror("signal error");return -1;}*///将SIGINT信号捕获if(signal(SIGINT, handler) == SIG_ERR){perror("signal error");return -1;}//绑定SIGTSTP信号 ctrl + zif(signal(SIGTSTP, handler) == SIG_ERR){perror("signal error");return -1;}while(1){sleep(1);printf("我真的还想再活五百年\n");}return 0;
}
(2)尝试捕获SIGSTOP信号
#include <head.h>//定义信号处理函数
void handler(int signum)
{if(signum == SIGINT) //表明要处理2号信号{printf("用户按下了ctrl + c键\n");}if(signum == SIGTSTP) //处理暂停信号{printf("用户按下了ctrl + z键\n");}if(signum == SIGSTOP) //处理暂停信号{printf("用户按下了ctrl + z键\n");}
}/****************************主程序********************/
int main(int argc, const char *argv[])
{/*尝试忽略SIGSTOP信号if(signal(SIGSTOP, SIG_IGN) == SIG_ERR){perror("signal error");return -1;}*//*尝试捕获SIGSTOP信号if(signal(SIGSTOP, handler) == SIG_ERR){perror("signal error");return -1;}*///尝试默认处理SIGSTOP信号if(signal(SIGSTOP, SIG_DFL) == SIG_ERR){perror("signal error");return -1;}while(1){sleep(1);printf("我真的还想再活五百年\n");}return 0;
}
(3)使用信号的方式以非阻塞的形式回收僵尸进程(SIGCHLD)
#include <head.h>//定义信号处理函数
void handler(int signum)
{if(signum == SIGCHLD){//以非阻塞的形式回收僵尸进程,直到所有的僵尸进程全部回收结束while(waitpid(-1, NULL, WNOHANG) >0 );}
}int main(int argc, const char *argv[])
{//捕获子进程发来的SIGCHLD信号if(signal(SIGCHLD, handler) == SIG_ERR){perror("signal error");return -1;}for(int i=0; i<10; i++){if(fork() == 0){exit(EXIT_SUCCESS);}}while(1);return 0;
}
(4)使用闹钟信号完成一个定时器(SIGALRM),该信号由alarm函数设置的时间超时后产生
#include <head.h>int main(int argc, const char *argv[])
{printf("%d\n", alarm(10)); //0sleep(5);printf("%d\n", alarm(10)); //5while(1);return 0;
}
(5)使用SIGALRM信号模拟斗地主出牌场景
#include <head.h>//定义信号处理函数
void handler(int signo)
{if(signo == SIGALRM){printf("系统已经随机为您出一张牌\n");alarm(5);}
}int main(int argc, const char *argv[])
{char ch;//将SIGALRM信号绑定到信号处理函数中if(signal(SIGALRM, handler) == SIG_ERR){perror("signal error");return -1;}while(1){alarm(5);printf("请出牌:");scanf("%c", &ch);getchar();printf("您出的牌为:%c\n", ch);}return 0;
}
(6)信号发送函数(kill、raise)
#include <head.h>//定义信号处理函数
void handler(int signo)
{if(signo == SIGUSR1){printf("逆子何至于此\n");raise(SIGKILL); //自杀}
}int main(int argc, const char *argv[])
{//定义进程号pid_t pid = fork();if(pid > 0){//父进程//将SIGUSR1信号绑定if(signal(SIGUSR1, handler) == SIG_ERR){perror("signal error");return -1;}while(1){printf("我真的还想再活五百年\n");sleep(1);}}else if(pid == 0){//子进程printf("人生得意须尽欢,莫使金樽空对月\n");sleep(3);printf("我看透了红尘, 父亲跟我一起走吧\n");//向父进程发送一个信号kill(getppid(), SIGUSR1);exit(EXIT_SUCCESS); //退出进程}else{perror("fork error");return -1;}return 0;
}
3.共享内存相关代码重新实现
(1)发送端
#include <head.h>
#define PAGE_SIZE 4096int main(int argc, const char *argv[])
{//1、创建key值key_t key = -1;if((key = ftok("/", 't')) == -1){perror("ftok error");return -1;}printf("key = %#x\n", key);//2、将物理内存创建出共享内存段int shmid = 0;if((shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664)) == -1){perror("shmget error");return -1;}printf("shmid = %d\n", shmid);//3、将共享内存段地址映射到用户空间//NULL表示让系统自动选择页的分段//0表示当前进程对共享内存具有读写功能char *addr = (char *)shmat(shmid, NULL, 0);if(addr == (void *)-1){perror("shmat error");return -1;}printf("addr = %p\n", addr);//4、操作共享内存//char buf[128] = "";while(1){fgets(addr, PAGE_SIZE, stdin); //从终端输入数据addr[strlen(addr) - 1] = '\0'; //将换行换成'\0'if(strcmp(addr, "quit") == 0){break;}}//5、取消映射while(1);return 0;
}
(2)接收端
#include <head.h>
#define PAGE_SIZE 4096int main(int argc, const char *argv[])
{//1、创建key值key_t key = -1;if((key = ftok("/", 't')) == -1){perror("ftok error");return -1;}printf("key = %#x\n", key);//2、将物理内存创建出共享内存段int shmid = 0;if((shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664)) == -1){perror("shmget error");return -1;}printf("shmid = %d\n", shmid);//3、将共享内存段地址映射到用户空间//NULL表示让系统自动选择页的分段//0表示当前进程对共享内存具有读写功能char *addr = (char *)shmat(shmid, NULL, 0);if(addr == (void *)-1){perror("shmat error");return -1;}printf("addr = %p\n", addr);//4、操作共享内存//char buf[128] = "";while(1){printf("共享内存中的数据为:%s\n", addr);sleep(1);if(strcmp(addr, "quit") == 0){break;}}//5、取消映射if(shmdt(addr) == -1){perror("shmdt error");return -1;}//6、删除共享内存if(shmctl(shmid, IPC_RMID, NULL) == -1){perror("shmctl error");return -1;}return 0;
}