Linux系统编程_进程:C程序空间分配、fork、wait、exec、system、popen

news2025/7/16 4:35:20

1. 进程相关概念(414.1)

问1. 什么是程序,什么是进程,有什么区别?

  • 程序是静态的概念,gcc xxx.c –o pro,磁盘中生成pro文件,叫做程序
  • 进程是程序的一次运行活动,通俗点即程序跑起来了,系统中就多了一个进程

问2. 如何查看系统中有哪些进程?

  • a. 使用ps指令查看进程,实际工作中配合grep来查找程序中是否存在某一进程
ps// 仅显示当前终端会话中运行的进程的快照
ps aux// 仅显示当前终端会话中运行的进程的快照
ps aux|grep xxx//显示包含特定进程名称xxx的进程。

在这里插入图片描述
在这里插入图片描述

  • b. 使用top指令查看进程实时情况,类似windows任务管理器
    在这里插入图片描述

问3. 什么是进程标识符?

  • 每个进程都有一个非负整数表示的唯一ID,叫做pid,类似身份证
    • Pid=0:称为交换进程(swapper),作用—进程调度
    • Pid=1:init进程,作用—系统初始化
  • 编程调用 getpid 函数获取自身的进程标识符,getppid 获取父进程的进程标识符
  • PRO/demo1.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	pid_t pid;

	pid = getpid();//获取自身的进程标识符

	printf("my pid is %d\n",pid);

	while(1);
	return 0;
}

问4. 什么叫父进程,什么叫子进程

  • 进程A创建了进程B:
    • 那么A叫做父进程,B叫做子进程
    • 父子进程是相对的概念,理解为人类中的父子关系

问5. C程序的存储空间是如何分配?(*面试会问)

在这里插入图片描述

在这里插入图片描述

2. 创建进程函数fork的使用(415.2)

使用fork函数创建一个进程:pid_t fork(void);

  • fork函数调用成功,返回两次
    • 返回值为 0, 代表当前进程是子进程
    • 返回值 非负数(>0),代表当前进程为父进程
    • 调用失败,返回 -1
  • 每一次a.out之后就是当前进程结束之后,重新a.out就是新的进程,so每个pid号不一样
    在这里插入图片描述
  • FILE/demo3.c
    在这里插入图片描述
  • FILE/demo4.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	pid_t pid;
	pid_t pid2;

	pid = getpid();
	printf("before fork: pid = %d\n\n",pid );	

	fork();
	
	pid2 = getpid();
	printf("after fork: pid = %d\n",pid2 );		

	if(pid == pid2){
		printf("this is father print,pid = %d\n\n",pid);fork创建之前的父进程id
	}
	else{
		printf("this is child print,child pid = %d\n",getpid());//fork创建之后的子进程id
	}
	return 0;
}

在这里插入图片描述

  • FILE/demo5.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	pid_t pid;

	printf("father: id =%d\n",getpid());

	pid = fork();
		
	if(pid > 0){
		printf("this is father print,pid = %d\n",getpid());
		
	}
	
	else if(pid == 0){
		printf("this is child print,pid = %d\n",getpid());
	}

	return 0;
}

3. 创建进程函数fork的使用补充(416.3)

  • FILE/demo6.c(fork的其一非正返回值表父进程,等于子进程pid号)
    在这里插入图片描述

4. 进程创建发生了什么事(417.4)

旧版本Linux的拷贝:全拷贝

新版本Linux的拷贝:写实拷贝(Copy-On-Write,COW)(*面试会问)

  • 父子进程在初始阶段共享所有的数据(全局、 栈区、 堆区、 代码), 内核会将所有的区域设置为只读。 当父子进程中任意一个进程试图修改其中的数据时, 内核才会将要修改的数据所在的区域(页) 拷贝一份。

  • 共享数据
    在这里插入图片描述

  • 写时拷贝后:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • FILE/demo7.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	pid_t pid;
	int data = 10;

	printf("father: id =%d\n",getpid());

	pid = fork();
		
	if(pid > 0){
		printf("this is father print,pid = %d\n",getpid());
		
	}
	
	else if(pid == 0){
		printf("this is child print,pid = %d\n",getpid());
		data = data+100;
	}
	
	printf("data=%d\n",data);
	
	return 0;
}

在这里插入图片描述

5. 创建新进程的实际应用场景及fork总结(418.5)

fork创建一个子进程的一般目的

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

fork编程实战

  • PRO/demo8.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	pid_t pid;
	int data = 10;

	while(1){

		printf("please input a data\n");
		scanf("%d",&data);	
		if(data == 1){
						
				pid = fork();
					
				if(pid > 0){
					
				}
				else if(pid == 0){
				
					while(1){
						printf("do net request,pid=%d\n",getpid());
						sleep(3);//使程序休眠3秒
					}
				}
		}
		else{
			printf("wait ,do nothing\n");
		}
	}

	return 0;
}

6. vfork创建进程(419.6)

  • PRO/demo9.c、demo10.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	pid_t pid;

	pid = fork();
	//pid = vfork();
		
	if(pid > 0){
		while(1){
			printf("this is father print, pid = %d\n",getpid());
			sleep(3);
		}	
	}
	else if(pid == 0){
		while(1){
			printf("this is chilid print, pid = %d\n",getpid());
			sleep(3);
		}	
	}
	
	return 0;
}
  • PRO/demo11.c
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>//exit函数的

int main(){
	pid_t pid;

	int cnt = 0;
	
	pid = vfork();
		
	if(pid > 0){
		while(1){
			printf("cnt=%d\n",cnt);
			printf("this is father print, pid = %d\n",getpid());
			sleep(1);
		}	
	}
	else if(pid == 0){
		while(1){
			printf("this is chilid print, pid = %d\n",getpid());
			sleep(1);
			cnt++;
			if(cnt == 3){
				exit(0);
				//_exit(0);
				//_Exit(0);
			}
		}	
	}
	return 0;
}

7. 进程退出(420.7)

  • 正常退出

    • Main函数调用return
    • 进程调用exit(),标准c库
    • 进程调用_exit()或者_Exit(),属于系统调用
    • 进程最后一个线程返回
    • 最后一个线程调用pthread_exit
  • 异常退出

    • 调用abort
    • 当进程收到某些信号时,如ctrl+C
    • 最后一个线程对取消(cancellation)请求做出响应

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8. 父进程等待子进程退出 (一)(421.8)

为啥要等待子进程退出

在这里插入图片描述

父进程等待子进程退出并收集子进程的退出状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • status参数:是一个整型数指针
    • 非空:子进程退出状态放在它所指向的地址中
    • 空:不关心退出状态
  • PRO/demo14.c
    在这里插入图片描述
  • PRO/demo15.c
    在这里插入图片描述

子进程退出状态不被收集,变成僵死进程(僵尸进程)

  • PRO/demo12.c(同demo11)(vfork,子进程退出后再父进程,子进程Z+僵尸进程)
  • PRO/demo13.c(fork无wait收集,子进程为僵尸进程,且父子进程先是交替运行)
    在这里插入图片描述

9. 父进程等待子进程退出 (二)(422.9)

waitpid

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • PRO/demo16.c(waitpid(pid,&status,WNOHANG);//不常用,不挂起不等待退出)
    在这里插入图片描述

孤儿进程

  • 父进程如果不等待子进程退出,在子进程之前就结束了自己的“生命”,此时子进程叫做孤儿进程
  • Linux避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程(pid=1)
  • PRO/demo17.c
    在这里插入图片描述

unix环境高级编程

  • 代码(子进程退出的状态判断)

在这里插入图片描述
在这里插入图片描述
运行结果:
在这里插入图片描述
在这里插入图片描述

10. exec族函数(423.10)

  • 精彩博文
    • https://blog.csdn.net/u014530704/article/details/73848573

为什么要用exec族函数,有什么作用

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • PRO/echoarg.c()
#include <stdio.h>

int main(int argc,char *argv[]){
    int i = 0;
    for(i = 0; i < argc; i++){
        printf("argv[%d]: %s\n",i,argv[i]); 
    }
    return 0;
}

在这里插入图片描述

  • PRO/demo18.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void){
    printf("before execl\n");
    
    if(execl("./echoarg","echoarg","abc",NULL) == -1){
        printf("execl failed!\n");      
	perror("why");
    }
    
    printf("after execl\n");
    
    return 0;
}

在这里插入图片描述

  • PRO/demo19.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void){
    printf("before execl\n");
    
    if(execl("/bin/ls","ls",NULL,NULL) == -1){
        printf("execl failed!\n");      
	perror("why");
    }
    
    printf("after execl\n");
    
    return 0;
}

在这里插入图片描述

  • PRO/demo20.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void){
    printf("before execl\n");
    
    if(execl("/bin/ls","ls","-l",NULL) == -1){
        printf("execl failed!\n");      
	perror("why");
    }
    
    printf("after execl\n");
    
    return 0;
}

在这里插入图片描述

  • PRO/demo21.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void){
    printf("this pro get system date:\n");
	
    if(execl("/bin/date","date",NULL,NULL) == -1){
        printf("execl failed!\n");      
	perror("why");
    }
    
    printf("after execl\n");
    
    return 0;
}

在这里插入图片描述

  • PRO/demo22.c(execlp函数带p,能通过环境变量PATH查找到可执行文件ps)(带p的只是省略了绝对路径,编译结果都一样)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void){
    printf("this pro get system date:\n");
	
    if(execlp("ps","ps",NULL,NULL) == -1){
        printf("execl failed!\n");      
	perror("why");
    }
    
    printf("after execl\n");
    
    return 0;
}

在这里插入图片描述
echo $PATH:让系统能找到这个路径底下的可执行程序
在这里插入图片描述

  • 将当前路径添加到系统环境变量(不用“./”、在别的目录下也可直接执行那个程序)
pwd//return:/home/cjq/Jessie/PRO
export PATH=$PATH:/home/cjq/Jessie/PRO

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • PRO/demo23.c(编译结果同demo22)(带v的只是多了一个char *argv)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void){
    printf("this pro get system date:\n");

    char *argv[] = {"ps",NULL,NULL};
    if(execvp("ps",argv) == -1){
        printf("execl failed!\n");      
	perror("why");
    }
    
    printf("after execl\n");
    
    return 0;
}
  • PRO/demo24.c(编译结果同demo22、23)(带v的只是多了一个char *argv)(不带p要加上绝对路径)
char *argv[] = {"ps",NULL,NULL};
    if(execv("/bin/ps",argv) == -1){

11. exec族函数配合fork使用(11)

在这里插入图片描述

  • 实现功能:当父进程检测到输入为1的时候,创建子进程把配置文件的字段值修改掉
  • PRO/demo25.c(仅使用子进程方式修改配置文件中的参数)
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>//wait的
#include <sys/wait.h>//wait的
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(){
	pid_t pid;
	int data = 10;

	while(1){
		printf("please input a data\n");
		scanf("%d",&data);	
		if(data == 1){
			int fdSrc;			
		
			pid = fork();
			
			if(pid > 0){
				wait(NULL);
			}	
			if(pid == 0){
				char *readBuf=NULL;

				fdSrc = open("config.txt",O_RDWR);
				int size = lseek(fdSrc,0,SEEK_END);
				lseek(fdSrc,0,SEEK_SET);

				readBuf=(char *)malloc(sizeof(char)*size + 8);
				int n_read = read(fdSrc, readBuf, size);

				char *p = strstr(readBuf,"LENG=");
				if(p==NULL){
					printf("not found\n");
					exit(-1);
				}
				p = p+strlen("LENG=");
				*p = '5';

				lseek(fdSrc,0,SEEK_SET);
				int n_write = write(fdSrc,readBuf,strlen(readBuf));
				
				close(fdSrc);
				exit(0);
			}
		}
		else{
			printf("wait ,do nothing\n");
		}
	}
	return 0;
}
  • PRO/demo26.c(子进程用exec调用另一程序来修改配置文件中的参数)
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>//wait的
#include <sys/wait.h>//wait的
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(){
	pid_t pid;
	int data = 10;

	while(1){
		printf("please input a data\n");
		scanf("%d",&data);	
		if(data == 1){
			int fdSrc;			
			pid = fork();
		
			if(pid > 0){
				wait(NULL);
			}	
			if(pid == 0){
				execl("./changeData","changeData","config.txt",NULL);
			}
		}
		else{
			printf("wait ,do nothing\n");
		}
	}
	return 0;
}

12. system函数(424.12)

在这里插入图片描述

  • 精彩博文:linux system 函数详解
    • https://www.cnblogs.com/leijiangtao/p/4051387.html
  • system()函数的返回值如下:
    • 成功,则返回进程的状态值;
    • 当sh不能执行时,返回127;
    • 失败返回-1;
  • PRO/demo27.c
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>//wait的
#include <sys/wait.h>//wait的
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(){
	pid_t pid;
	int data = 10;

	while(1){
		printf("please input a data\n");
		scanf("%d",&data);	
		if(data == 1){
			int fdSrc;			
		
			pid = fork();
			
			if(pid > 0){
				wait(NULL);
			}	
			if(pid == 0){
				
				//execl("./changeData","changeData","config.txt",NULL);
				system("./changeData config.txt");//相当于在终端执行shell命令“sh -c ./changeData config.txt”
			}
		}
		else{
			printf("wait ,do nothing\n");
		}
	}
	return 0;
}

在这里插入图片描述

13. popen函数(425.13)

在这里插入图片描述

  • 精彩博文:popen
    • https://blog.csdn.net/libinbin_1014/article/details/51490568
  • 比system在应用中的好处:
    • 可以获取运行的输出结果
  • PRO/demo28.c(system(exec)运行成功不返回)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void){
    char ret[1024] = {0};

    system("ps");
    printf("ret=%s\n",ret);
	//popen("ps","w");
    return 0;
}
  • PRO/demo29.c(popen返回运行结果)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
int main(void){
    char ret[1024] = {0};
    FILE *fp;

    fp = popen("ps","r");
    int nread = fread(ret,1,1024,fp);	

    printf("read ret %d byte, ret=%s\n",nread,ret);
	    
    return 0;
}

14. 进程总结(426.14)(重点:1 2 3 4 5 12 13节课程)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1102952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LoongArch单机Ceph Bcache加速4K随机写性能测试

LoongArch单机Ceph Bcache加速4K随机写性能测试 两块HDD做OSD [rootceph01 ~]# fio -direct1 -iodepth128 -thread -rwrandwrite -ioenginelibaio -bs4k -size100G -numjobs1 -runtime600 -group_reporting -namemytest -filename/dev/rbd0 mytest: (g0): rwrandwrite, bs(R)…

System.exit()方法参数

说明文档&#xff1a;System (Java Platform SE 8 ) 终止当前正在运行的Java虚拟机。该参数用作状态代码&#xff1b;按照惯例&#xff0c;非零状态码表示异常终止。 此方法调用类Runtime中的exit方法。此方法从不正常返回。 调用System.exit&#xff08;n&#xff09;实际上等…

这应该是关于回归模型最全的总结了(附原理+代码)

本文将继续修炼回归模型算法&#xff0c;并总结了一些常用的除线性回归模型之外的模型&#xff0c;其中包括一些单模型及集成学习器。 保序回归、多项式回归、多输出回归、多输出K近邻回归、决策树回归、多输出决策树回归、AdaBoost回归、梯度提升决策树回归、人工神经网络、随…

个人博客系统的总结

个人博客系统 1、项目背景&#xff1a; 个人博客系统的兴起和发展是与信息技术和互联网的迅猛发展密切相关的。随着互联网的普及和数字化时代的到来&#xff0c;越来越多的人开始使用互联网平台来表达自己的观点、分享知识和展示个人创作。个人博客系统作为一种在线的个人信息…

C# CodeFormer Inpainting 人脸填充

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace CodeFormer_D…

Qt系列-QSplitter使用笔记

Qt拆分窗口可以使用QSplitter&#xff0c;也可以使用比较容易使用布局控件来完成&#xff0c;如果有需要对界面进行切割&#xff0c;可以使用QSplitter进行简易的控件拼接。 注意&#xff1a;QSplitter 继承自QFrame&#xff0c;而QFrame又继承自QWidget&#xff0c;这点很重要…

数据结构----算法--五大基本算法

数据结构----算法–五大基本算法 一.贪心算法 1.什么是贪心算法 在有多个选择的时候不考虑长远的情况&#xff0c;只考虑眼前的这一步&#xff0c;在眼前这一步选择当前的最好的方案 二.分治法 1.分治的概念 分治法&#xff1a;分而治之 将一个问题拆解成若干个解决方式…

代码随想录第44天 | ● 1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和 动态规划

1143.最长公共子序列 //*** param {string} text1* param {string} text2* return {number}*/ var longestCommonSubsequence function(text1,text2) {let dp new Array(text2.length1)dp.fill(0)for(let i 1; i < text1.length; i) {// 这里pre相当于 dp[i - 1][j - 1]…

这些 channel 用法你都用起来了吗?

channel 是什么&#xff1f; channel 是GO语言中一种特殊的类型&#xff0c;是连接并发goroutine的管道 channel 通道是可以让一个 goroutine 协程发送特定值到另一个 goroutine 协程的通信机制。 关于 channel 的原理&#xff0c;channel通道需要注意的地方&#xff0c;之前…

Kotlin中布尔类型、字符类型、字符串类型和数组类型

在Kotlin中&#xff0c;布尔类型、字符类型、字符串类型和数组类型是常用的数据类型之一。下面我将对它们进行详细描述并提供示例代码。 布尔类型&#xff08;Boolean&#xff09;&#xff1a; 布尔类型表示逻辑值&#xff0c;只有两个可能的取值&#xff1a;true和false。在K…

我的创作纪念日———C/C++之动态内存管理

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2.为什么要有动态内存分配…

浅谈工业企业能源管理软件的应用

安科瑞 崔丽洁 摘要&#xff1a;在工业企业中&#xff0c;能源是企业正常工作的根本保障&#xff0c;同时也是工业企业成本的主要构成部分。工业企业在相应的工作和使用的能源包括水、电、气等。在过去&#xff0c;企业对能源消耗的关注度比较低&#xff0c;更多的强调安全与保…

二分查找算法(Python)

目录 1、概念 2、思路 3、实现算法 1、概念 二分查找又称折半查找&#xff0c;它是一种效率较高的查找方法 原理&#xff1a;首先&#xff0c;假设表中元素是按升序排列&#xff0c;将表中间位置记录的关键字与查找关键字比较&#xff0c;如果两者相等&#xff0c;则查找成…

从入门到进阶 之 ElasticSearch 文档、分词器 进阶篇

&#x1f339; 以上分享 ElasticSearch 文档、分词器 进阶篇&#xff0c;如有问题请指教写。&#x1f339;&#x1f339; 如你对技术也感兴趣&#xff0c;欢迎交流。&#x1f339;&#x1f339;&#x1f339; 如有需要&#xff0c;请&#x1f44d;点赞&#x1f496;收藏&#…

通达OA 2016网络智能办公系统 handle.php SQL注入漏洞

一、漏洞描述 北京通达信科科技有限公司通达OA2016网络智能办公系统 handle.php 存在sql注入漏洞&#xff0c;攻击者可利用此漏洞获取数据库管理员权限&#xff0c;查询数据、获取系统信息&#xff0c;威胁企业单位数据安全。 二、网络空间搜索引擎查询 fofa查询 app"T…

攻防演练蓝队|Windows应急响应入侵排查

文章目录 日志分析web日志windows系统日志 文件排查进程排查新增、隐藏账号排查启动项/服务/计划任务排查工具 日志分析 web日志 dirpro扫描目录&#xff0c;sqlmap扫描dvwa Python dirpro -u http://192.168.52.129 -b sqlmap -u "http://192.168.52.129/dvwa/vulnera…

牛客:FZ12 牛牛的顺时针遍历

FZ12 牛牛的顺时针遍历 文章目录 FZ12 牛牛的顺时针遍历题目描述题解思路题解代码 题目描述 题解思路 通过一个变量来记录当前方向&#xff0c;遍历矩阵&#xff0c;每次遍历一条边&#xff0c;将该边的信息加入到结果中 题解代码 func spiralOrder(matrix [][]int) []int {…

小程序-uni-app:将页面(html+css)生成图片/海报/名片,进行下载 保存到手机

一、需要描述 本文实现&#xff0c;uniapp微信小程序&#xff0c;把页面内容保存为图片&#xff0c;并且下载到手机上。 说实话网上找了很多资料&#xff0c;但是效果不理想&#xff0c;直到看了一个开源项目&#xff0c;我知道可以实现了。 本文以开源项目uniapp-wxml-to-can…

Mysql——查询sql语句练习

一、单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 1、显示所有职工的基本信息。 select * from worker; 2、查询所有职工所属部门的部门号&#xff0c;不显示重复的部门号。 select distinct 部门号…

开发万岳互联网医院APP:技术要点和关键挑战

随着移动技术和互联网的飞速发展&#xff0c;互联网医院APP成为医疗领域的一项重要创新。这些应用程序为患者和医生提供了更多便利和互动性&#xff0c;但开发互联网医院APP也伴随着一系列的技术要点和关键挑战。本文将探讨互联网医院APP的技术要点以及在开发过程中需要面对的挑…