当前位置: 首页 > news >正文

设计用哪些网站有哪些江阴网站优化公司

设计用哪些网站有哪些,江阴网站优化公司,电子商务网站建设与原理,建立网站可以赚钱吗?1.进程间的通信进程空间是独立的,包含文本段、数据段和系统数据段,多个进程没有共享的用户空间,进程是操作系统资源分配的最小单元,可以利用Linux内核实现多个进程间的通信。2.进程间常见的通信方式传统Unix系统中的通信方式&…

1.进程间的通信

        进程空间是独立的,包含文本段、数据段和系统数据段,多个进程没有共享的用户空间,进程是操作系统资源分配的最小单元,可以利用Linux内核实现多个进程间的通信。

              

2.进程间常见的通信方式

        传统Unix系统中的通信方式:管道,信号。

        SYS V分支中的通信方式:消息队列,共享内存,信号灯。

        BSD分支中的通信方式:本地域套接字。

3.管道

管道操作特性:

        1. 管道中至少有一个写端: 读取数据时,如果管道中有数据则直接读出 读取数据时,如果管道中没有数据则阻塞等待有数据写入才能读出。

        2. 管道中没有写端: 读取数据时,管道中有数据则直接读出 读取数据时,管道中没有数据不阻塞等待直接向下执行。

        3. 管道中至少有一个读端: 写入数据时,如果管道没有写满则直接写入 写入数据时,如果管道存满则阻塞等待有数据读出才能继续写入。

        4. 管道中没有读端:写入数据时,会产生管道破裂的信号导致进程任务异常退出。

3.1无名管道(只能用于有亲缘关系的进程间)

        无名管道是一段内核缓存区,父进程通过pipe创建无名管道,只有该父进程的子进程才能继承得到这两个文件描述符,才能实现通信,因此只能用于具有亲缘关系的进程间通信。

         

3.1.1函数接口pipe:创建一个无名管道(内核缓存区)。

原型:int pipe(int pipefd[2]);
功能:
创建一个无名管道(内核缓存区)
参数:
pipefd[0]:读管道文件描述符
pipefd[1]:写管道文件描述符
返回值:
成功返回0 
失败返回-1

无名管道在父子进程间的应用:

#include "head.h"int main(void)
{int pipefd[2];      // 定义管道文件描述符数组,pipefd[0]为读端,pipefd[1]为写端int ret = 0;        // 用于存储函数返回值pid_t pid;          // 进程ID变量char tmpbuff[4096] = {0}; // 缓冲区,用于读写数据// 创建匿名管道ret = pipe(pipefd);if (-1 == ret)      // 检查管道是否创建成功{perror("fail to pipe"); // 打印错误信息return -1;}// 创建子进程pid = fork();if (-1 == pid)      // 检查fork是否成功{perror("fail to fork");return -1;}// 子进程逻辑if (0 == pid){strcpy(tmpbuff, "hello world");              // 子进程写入数据到缓冲区write(pipefd[1], tmpbuff, strlen(tmpbuff));  // 向管道写端写入数据sleep(1);                                    // 等待1秒(确保父进程先读)read(pipefd[0], tmpbuff, sizeof(tmpbuff));   // 从管道读端读取父进程的回复printf("子读 = %s\n", tmpbuff);              // 打印读取的数据}// 父进程逻辑else if (pid > 0){read(pipefd[0], tmpbuff, sizeof(tmpbuff));   // 从管道读端读取子进程的数据printf("父读 = %s\n", tmpbuff);              // 打印读取的数据write(pipefd[1], "thank you", 10);           // 向管道写端回复数据}// 关闭管道的两端(父子进程各自关闭自己的文件描述符)close(pipefd[0]);close(pipefd[1]);return 0;
}

3.2有名管道

        有名管道与无名管道区别:有名管道有名字,可以通过名字找到该管道,可以用于任意进程间的通信,是进程间通信最简单、易实现的方式,且有名管道必须读写两端同时加入才能继续向下执。

                 

3.2.1函数接口mkfifo:创建有名管道

原型:int mkfifo(const char *pathname, mode_t mode);
功能:
创建有名管道
参数:
pathname:管道文件名
mode:权限
返回值:
成功返回0 
失败返回-1 

3.2.2操作方式

1. 进程一使用open以读、写、读写方式打开管道文件
2. 进程二使用open以读、写、读写方式打开管道文件
3. 两个进程可以通过向管道文件中读写数据实现进程的通信

        write向管道1写入字符串,read读取管道1的内容打印在终端并向管道二写入字符串,再由write读取管道二的内容并打印:

//read
#include "head.h"
int main(void)
{int fd1 = 0;int fd2 = 0;char tmpbuff[4096] = {0};mkfifo("./myfifo1", 0777);fd1 = open("./myfifo1", O_RDWR);if (-1 == fd1){perror("fail to open");return -1;}mkfifo("./myfifo2", 0777);fd2 = open("./myfifo2", O_RDWR);if (-1 == fd2){perror("fail to open");return -1;}while (1){memset(tmpbuff, 0, sizeof(tmpbuff));read(fd1, tmpbuff, sizeof(tmpbuff));printf("RECV:%s\n", tmpbuff);memset(tmpbuff, 0, sizeof(tmpbuff));m_fgets(tmpbuff);write(fd2, tmpbuff, strlen(tmpbuff)); }close(fd1);close(fd2);return 0;
}
//write
#include "head.h"
int main(void)
{int fd1 = 0;int fd2 = 0;char tmpbuff[4096] = {0};mkfifo("./myfifo1", 0777);fd1 = open("./myfifo1", O_RDWR);if (-1 == fd1){perror("fail to open");return -1;}mkfifo("./myfifo2", 0777);fd2 = open("./myfifo2", O_RDWR);if (-1 == fd2){perror("fail to open");return -1;}while(1){memset(tmpbuff, 0, sizeof(tmpbuff));m_fgets(tmpbuff);write(fd1, tmpbuff, strlen(tmpbuff));  memset(tmpbuff, 0, sizeof(tmpbuff));read(fd2, tmpbuff, sizeof(tmpbuff));printf("RECV:%s\n", tmpbuff);}close(fd1);close(fd2);return 0;
}

        这串代码只能实现两个进程间轮流发送并打印,无法做到某个进程一直向对方发送并打印,因此我们可以加入两个线程,搭配管道实现聊天功能:

      

//clientA.c
#include "head.h"
void *thread1(void *arg)
{int fd1 = 0;fd1 = open("./myfifo1", O_WRONLY);char tmpbuff[4096] = {0};while(1){memset(tmpbuff, 0, sizeof(tmpbuff));m_fgets(tmpbuff);write(fd1, tmpbuff, strlen(tmpbuff));}close(fd1);return NULL;
}
void *thread2(void *arg)
{int fd2 = 0;fd2 = open("./myfifo2", O_RDONLY);char tmpbuff[4096] = {0};while (1) {read(fd2, tmpbuff, sizeof(tmpbuff));printf("收到的消息: %s\n", tmpbuff);memset(tmpbuff, 0, sizeof(tmpbuff));}close(fd2);return NULL;
}
int main(void)
{mkfifo("./myfifo1", 0777);mkfifo("./myfifo2", 0777);pthread_t tid[2] = {0};pthread_create(&tid[0], NULL, thread1, NULL);pthread_create(&tid[1], NULL, thread2, NULL);pthread_join(tid[0],NULL);pthread_join(tid[1],NULL);return 0;
}
//clientB.c
#include "head.h"
void *thread1(void *arg)
{int fd1 = 0;fd1 = open("./myfifo1", O_RDONLY);char tmpbuff[4096] = {0};while(1){read(fd1, tmpbuff, sizeof(tmpbuff));printf("收到的消息: %s\n", tmpbuff);memset(tmpbuff, 0, sizeof(tmpbuff));}close(fd1);return NULL;
}
void *thread2(void *arg)
{int fd2 = 0;fd2 = open("./myfifo2", O_WRONLY);char tmpbuff[4096] = {0};while (1) {memset(tmpbuff, 0, sizeof(tmpbuff));m_fgets(tmpbuff);write(fd2, tmpbuff, strlen(tmpbuff));}close(fd2);return NULL;
}
int main(void)
{mkfifo("./myfifo1", 0777);mkfifo("./myfifo2", 0777);pthread_t tid[2] = {0};pthread_create(&tid[0], NULL, thread1, NULL);pthread_create(&tid[1], NULL, thread2, NULL);pthread_join(tid[0],NULL);pthread_join(tid[1],NULL);return 0;
}

4.信号

        Linux系统中的信号主要实现应用层和内核层之间的信号通知,应用层与内核层之间通信的信号根据含义分为很多不同的信号,信号主要用于多个进程任务间的事件通知,信号可以用于异步通信。

                ​​​​​​​        ​​​​​​​        

4.1信号的类型

        使用kill -l 查看信号类型:

linux@ubuntu:~$ kill -l1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX
SIGINT:中止信号(可以从键盘输入)        ctrl + c
SIGQUIT:退出信号(可以从键盘输入)       ctrl + \
SIGKILL:杀死进程信号
SIGSEGV:段错误信号
SIGPIPE:管道破裂信号
SIGALARM:定时时间到达信号
SIGCHLD:子进程结束时,父进程回收到该信号
SIGCONT:继续执行进程任务
SIGSTOP:停止进程任务
SIGTSTP:挂起信号(可以从键盘输入)       ctrl + z
SIGIO:异步IO信号

4.2信号的处理方式

缺省接到信号,按照默认方式处理
忽略接到信号,不处理信号,忽略信号
捕捉接到信号,按照用户自己定义的方式处理信号

        需要注意:9号信号(SIGKILL)和19号信号(SIGSTOP)不能被忽略和捕捉的。

4.3函数接口

4.3.1signal设置signum对应信号的处理方式

原型:
typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);
功能:设置signum对应信号的处理方式
参数:signum:信号的编号handler:信号的处理方式SIG_IGN:忽略信号SIG_DFL:缺省处理信号
返回值:成功返回之前处理信号的方式失败返回SIG_ERR

运行程序等待终端的不同信号打印不同的字符串:

#include "head.h"/* 信号处理函数1:处理SIGINT信号(Ctrl+C触发) */
void handler1(int signo)
{printf("SIGINT信号来了!\n");  // 打印信号提示return;
}
/* 信号处理函数2:处理SIGQUIT信号(Ctrl+\触发) */
void handler2(int signo)
{printf("SIGQUIT信号来了!\n"); // 打印信号提示return;
}
/* 信号处理函数3:处理SIGTSTP信号(Ctrl+Z触发) */
void handler3(int signo)
{printf("SIGTSTP信号来了!\n"); // 打印信号提示return;
}
int main(void)
{// 注册信号处理函数signal(SIGINT, handler1);signal(SIGQUIT, handler2);signal(SIGTSTP, handler3);// 保持程序运行,等待信号while (1){}return 0;
}
#if 0 
/* 优化版本:使用单一处理函数通过参数区分不同信号 */
#include "../head.h"/* 通用信号处理函数 */
void handler(int signo)
{if (SIGINT == signo)        // 判断是否为SIGINT信号{printf("SIGINT信号来了\n");}else if (SIGQUIT == signo)  // 判断是否为SIGQUIT信号{printf("SIGQUIT信号来了\n");}else if (SIGTSTP == signo)  // 判断是否为SIGTSTP信号{printf("SIGTSTP信号来了\n");}return;
}int main(void)
{// 注册信号处理函数(全部使用handler)signal(SIGINT, handler);signal(SIGQUIT, handler);signal(SIGTSTP, handler);while (1){}return 0;
}
#endif

        ​​​​​​​        ​​​​​​​        ​​​​​​​       ​​​​​​​

可以用ps -ef | grep filename查看进程,kill -9 pid杀死进程结束当前程序:

        ​​​​​​​        

4.3.2alarm设置第一个定时,过seconds秒后,给进程发送SIGALRM信号

原型:unsigned int alarm(unsigned int seconds);
功能:
设置第一个定时,过seconds秒后,给进程发送SIGALRM信号
参数:
seconds:秒数
返回值:
成功返回上次定时剩余的秒数
如果之前没有定时返回0 

应用示例:

#include "head.h"  // 包含自定义头文件
/* SIGALRM信号处理函数 */
void handler(int signo)
{printf("SIGALRM信号来了\n");  // 打印信号到达提示alarm(5);                    // 重新设置5秒后再次触发SIGALRMreturn;
}
int main(void)
{// 注册SIGALRM信号的处理函数signal(SIGALRM, handler);// 设置第一个5秒定时器,5秒后发送SIGALRM信号alarm(5);while (1){printf("正在运行...\n");sleep(1);}return 0;
}

          ​​​​​​​        ​​​​​​​

4.3.3kill给pid对应的进程发送sig信号

原型:int kill(pid_t pid, int sig);
功能:
给pid对应的进程发送sig信号
参数:
pid:进程的ID号
sig:信号的编号
返回值:
成功返回0 
失败返回-1 
  1. Ctrl+C → 子进程收到 SIGINT → 子进程向父进程发送 SIGUSR1 → 父进程打印消息

  2. Ctrl+\ → 父进程收到 SIGQUIT → 父进程向子进程发送 SIGUSR2 → 子进程打印消息

#include "head.h"pid_t pid;void handler_parent(int signo)
{if (SIGQUIT == signo){kill(pid, SIGUSR2);}else if (SIGUSR1 == signo){printf("父进程:收到子进程发送的信号了\n");}return;
}
void handler_child(int signo)
{if (SIGINT == signo){kill(getppid(), SIGUSR1);}else if (SIGUSR2 == signo){printf("子进程:收到父进程发送的信号了\n");}return;
}
int main(void)
{pid = fork();if (-1 == pid){perror("fail to fork");return -1;}if (0 == pid){signal(SIGUSR2, handler_child);signal(SIGINT, handler_child);signal(SIGQUIT, SIG_IGN);}else if (pid > 0){signal(SIGUSR1, handler_parent);signal(SIGQUIT, handler_parent);signal(SIGINT, SIG_IGN);}while (1){}return 0;
}
http://www.dtcms.com/a/410520.html

相关文章:

  • 网站对企业的重要性网络网页设计制作公司
  • 在 CentOS 7.6 上安装 Oracle WebLogic Server 12c 详细教程
  • Android,jetpack,compose,简单模仿水果消消乐
  • 小迪安全v2023学习笔记(八十八讲)—— 安卓逆向篇JEB反编译断点动态调试加密算法还原逻辑会员绕过
  • 无人机作业分析平台的实际应用怎么样?
  • 网站开发准备统计wordpress
  • 用trea导入keil的工程文件
  • GitOps:一种实现云原生的持续交付模型
  • 可以做调查的网站wordpress修改后台
  • 废品回收小程序:从 “扔垃圾“ 到 “变资源“ 的体验革命
  • 快手小程序踩坑——首屏数据预取踩坑记录
  • 乔拓云门店小程序快速搭建攻略
  • IP新定义下的商业新范式:基于定制开发开源AI智能名片S2B2C商城小程序的IP价值变现研究
  • 个人游戏网站备案wordpress获取tag
  • 淘宝网站建设基本流程图男女做那个暖暖网站
  • 【超详细】C#自定义工具类-FileHelper文件工具类
  • 43.传输层协议TCP(下)
  • wordpress 会议网站设计网站网站名称
  • wordpress设置多站点西安市建筑工程信息网
  • 政务系统国产化的“教科书级“实践:MongoDB平滑迁移成功案例解析
  • 乾元通渠道商中标民勤县应急指挥能力提升项目
  • 编程语言top5对比分析!
  • 【第五章:计算机视觉-项目实战之图像分割实战】1.图像分割理论-(2)图像分割衍生:语义分割、实例分割、弱监督语义分割
  • 5G开户中的RAT限制(无线接入技术限制)
  • PHP 快速集成 ChatGPT 用 AI 让你的应用更聪明
  • 网站推销话术深圳前十vi设计公司
  • 2025 PHP7/8 实战入门:15 天精通现代 Web 开发——第 14 课:安全开发实践
  • 中国网站的建设家装公司网站建设
  • VS类设计器
  • 大数据数仓笔试题