热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

有名管道,精灵进程

编程实现两个程序:一个服务器server,一个客户机client。要求:服务器采用精灵进程的方式在后台运行,常驻内存。服务器

编程实现两个程序:一个服务器server,一个客户机client。
要求:
服务器采用精灵进程的方式在后台运行,常驻内存。
服务器创建并监视有名管道FIFO,一旦发现有数据,服务器将其保存到一个指定的地方。
客户机每隔一段时间产生一个子进程。
客户机的这些子进程将当前系统时间和自身的PID写入有名管道FIFO就退出。

要点:有名管道,进程间的通信

客户端:

#include "common.h" //头文件就是包含使用到的函数// 信号的响应处理函数,函数头(接口)是系统规定的
void cleanup(int sig)
{// 回收僵尸子进程wait(NULL);// 使用非阻塞版本来回收僵尸子进程// -1: 查看任意子进程死了没有// NULL: 对子进程怎么死(退出状态)的不感兴趣// WNOHANG: 非阻塞回收(如果死了就立刻释放其资源,如果没死拉倒,我就走了)while(waitpid(-1, NULL, WNOHANG) > 0);
}int main()
{// 关联子进程终止的信号及其处理函数signal(SIGCHLD, cleanup);while(1){pid_t pid = fork();// 父进程if(pid > 0){sleep(1);continue;}// 子进程if(pid == 0){// 1,打开预谋好的管道int fd = open("/home/gec/fifo", O_WRONLY);if(fd == -1){perror("服务器未启动或管道文件打开失败");exit(0);}// 2,将系统时间、自身PID放入buf中char buf[50];bzero(buf, 50);time_t t = time(&t);snprintf(buf, 50, "PID:%d 时间:%s",getpid(), ctime(&t));// 3,将buf中的数据写入管道write(fd, buf, strlen(buf));printf("%s", buf);break;}}return 0;
}

服务端

#include "common.h"static bool begin = true;
static FILE *fp;void saveData(const char *buf, int size)
{if(begin){fp = fopen("/home/gec/mylog", "a+");begin = false;}// 将数据写入文件,并刷新缓冲区fwrite(buf, size, 1, fp);fflush(fp);
}
void mylog(const char *usrmsg, const char *errmsg)
{char buf[100];bzero(buf, 100);snprintf(buf, 100, "%s:%s\n", usrmsg, errmsg);syslog(LOG_DAEMON, buf);
}int daemon_init(void)
{pid_t pid;int fd0, fd1, fd2, max_fd,i; // 1if((pid &#61; fork()) < 0){perror("fork faild!");exit(1);}else if(pid > 0){exit(0);}printf("第1步成功\n");// 2signal(SIGHUP, SIG_IGN);printf("第2步成功\n");// 3if(setsid() < 0){exit(1);}printf("第3步成功\n");// 4if((pid &#61; fork()) < 0){perror("fork faild!");exit(1);}else if(pid > 0)exit(0);printf("第4步成功\n");// 5setpgrp();printf("第5步成功\n");// 6// 准备好写系统日志openlog("Server", LOG_CONS | LOG_PID, LOG_DAEMON);// 7// 首先获取进程所能打开的文件描述符的最大值max_fd &#61; sysconf(_SC_OPEN_MAX);// 将所有的文件描述符全部关闭&#xff08;包括标准输入、输出&#xff09;for (i &#61; max_fd; i>&#61;0; i--){close(i);}// 7umask(0);// 8chdir("/");return 0;
}int main()
{// 1&#xff0c;变神仙daemon_init();// 2&#xff0c;创建管道&#xff0c;并打开管道mkfifo("/home/gec/fifo", 0666);int fd &#61; open("/home/gec/fifo", O_RDWR);if(fd &#61;&#61; -1){mylog("打开管道失败", strerror(errno));exit(0);}// 3&#xff0c;不断地将管道数据读出并保存char buf[50];while(1){bzero(buf, 50);int n &#61; read(fd, buf, 50);if(n > 0){saveData(buf, n);}else{mylog("读取管道数据失败", strerror(errno));exit(0);}}fclose(fp);close(fd);return 0;
}

思路与步骤&#xff1a;

一、客户端步骤&#xff1a;


  1. 打开有名管道
  2. 往管道写入数据
  3. 管道的读写是在子进程进程进行&#xff0c;执行完任务后就退出了。所以父进程要回收子进程&#xff0c;避免僵尸的长期存在。

二、服务端步骤


  1. 创建有名管道
  2. 打开有名管道
  3. 阻塞等待客户端的信息
  4. 有数据来的话就创建一个文件来保存客户端的数据
  5. 服务端应该为一个精灵进程&#xff0c;即我当前的控制终端关闭也不影响我持续不断的监控客户端的数据。

推荐阅读
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
author-avatar
手机用户2502868585
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有