C++学习记录 - 进程创建

1. 创建进程

c/c++中,使用fork()函数创建一个进程。

pid_t pid = fork();

子进程自fork()以后开始执行。

fork()函数返回值,为pid_t类型,父子进程依靠pid的不同进行区分。如果fork失败,pid为-1;如果fork成功的话,对于父进程来说,pid是一个正整数,对于子进程来说,pid为0。

子进程创建后,为了节省资源,父子进程之间的共享,遵循读时共享,写时复制的原则。

父子进程共享:1. 文件描述符。 2. mmap建立的映射区。注意,程序中的全局变量什么的,都是独立的,不共享。

fork以后,父进程先执行还是子进程先执行,取决于内核所使用的进程调度算法

2. exec函数族

进程当中去执行另外的程序可以使用exec函数族。

当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行,调用exec并不会创建新的进程,所以调用exec前后该进程的id并未改变。

2.1 execlp

2.2 execl

3. 回收子进程

孤儿进程:父进程比子进程先结束,则该子进程为孤儿进程。此时,子进程的父进程成为init进程,称为init进程领养孤儿进程。但是,实际测试发现,在ubuntu16.04环境下,不是被init进程领养,而是被/sbin/upstart进程领养
在这里插入图片描述

僵尸进程:子进程进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸进程。
使用kill命令无法终止僵尸进程,因为kill命令只能用来终止进程,而僵尸进程已经终止了。

3.1 wait函数

#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);
  • 阻塞等待子进程退出
  • 回收子进程残留资源
  • 获取子进程结束状态(退出原因)

一个wait函数只能回收一个子进程,如果有多少子进程的话,谁先结束,就回收谁。

3.2 waitpid函数

#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

功能上包含了wait函数。

4. 进程间通信(IPC)

  • 管道(使用最简单)
  • 信号(开销最小)
  • 共享映射区(也叫共享内存)(无血缘关系)
  • 本地套接字(最稳定)

4.1 管道(PIPE)

  • 管道是一个伪文件,是内核中的一块缓冲区(默认4k,可以通过ulimit -a查看)。

  • 管道一端读,一端写。

  • 管道是半双工通信(单向交替传输)。

  • 管道中的数据,读出了就没了,管道不进行保存,也就是说不能反复读取。

  • 管道只能在有血缘关系的进程间使用。

关键函数是pipe()

#include <unistd.h>

int pipe(int pipefd[2]);

// fd[0] 读端。
// fd[1] 写端。

4.2 有名管道(FIFO)

4.3 共享映射区(共享内存)

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

有血缘关系的进程间通信,测试代码:

#include <iostream>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <stdio.h>
#include <sys/wait.h>
#include <string.h>

#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>


using std::cout;
using std::cin;
using std::endl;

int var = 100;

int main(int argc, char const *argv[])
{   

	
	int *p;
	int len = 4;  // 建立映射区的大小

	
	p = (int *)mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
	
	if(p == MAP_FAILED){  // 注意  不是 p == -1
		cout << "mmap error" << endl;
		return -1;
	}
	
	pid_t pid = fork();
	if(pid == 0){
		*p = 2000;
		var = 1000;
		printf("child,*p = %d, var = %d\n", *p, var);

	}else{
	
		// 父进程
		sleep(1);
		printf("parent,*p = %d, var = %d\n", *p, var);   // 这里的var输出100,因为父子进程间不共享全局变量
		wait(nullptr);
		
		
		int ret = munmap(p, len);
		if(ret == -1){
			cout << "munmap error" << endl;
			return -1;
		}
	
	}
	

	
    return 0;
}
  • MAP_SHARED 共享映射,父子进程共享映射区。
  • MAP_PRIVATE 私有映射,父子进程各自独占映射区。

4.4 本地套接字

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android C 高级编程是指在Android开发中使用C语言进行高级编程的技术。而使用NDK(Native Development Kit)可以使开发者在Android应用中使用C/C++等本地语言进行编程。 NDK是一个工具集,它允许开发者在Android应用中嵌入本地代码,并且提供了一系列的开发工具和库,以便开发者能够在Android应用中使用C/C++进行高级编程。使用NDK可以提供更高的性能和更低的内存占用,适用于需要处理大量数据和高性能计算的应用场景。 在使用NDK进行Android C高级编程时,可以使用PDF(Portable Document Format)作为文档格式,以便对代码和项目进行更好的管理和文档化。在NDK的开发过程中,可以使用PDF文档记录关键的设计思路、代码逻辑、接口定义等信息,以方便团队协作和后续的维护。 使用NDK进行Android C高级编程的步骤大致如下: 1. 准备开发环境:安装NDK并配置好开发环境,包括设置NDK的路径和编译器等。 2. 创建新项目:使用Android Studio创建一个新的Android项目,并在项目中引入NDK的支持。 3. 编写C代码:使用C/C++语言编写需要调用的函数、算法或者数据结构等代码,并将其保存在适当的目录下。 4. 编写JNI接口:在生成的Java代码中,使用JNI(Java Native Interface)定义对应C代码的接口,以便在Java层调用C代码。 5. 编译和构建:使用NDK的工具集进行编译和构建,将C代码编译成适合Android平台使用的库文件(.so文件)。 6. 在Java代码中调用C代码:在需要调用C代码的地方,使用JNI接口调用对应的C函数,以实现和C代码的交互和调用。 使用PDF文档进行文档化可以帮助开发者更好地组织和管理代码、接口和设计文档等,方便后续的代码维护和项目协作。同时,也可以作为项目的参考文档,方便其他开发人员了解和使用项目。 ### 回答2: Android C 高级编程是针对使用NDK(Native Development Kit)的一种高级编程技术。NDK是Android开发工具包中的一个工具,允许开发者使用C、C++或其他本地编程语言编写Android应用程序的部分或全部代码。 使用NDK进行Android C高级编程有许多优点。首先,NDK提供了更高的性能和更好的控制权,特别是在处理图形、音频和计算密集型任务时。通过使用本地编程语言,开发者能够更好地利用底层系统资源,提高应用程序的执行效率和速度。 其次,NDK还提供了对现有C和C++库的支持。这意味着开发者可以使用许多已经存在的库和功能来加快开发进程。无需重新编写现有的代码,直接使用NDK与这些库进行集成即可。 在使用NDK进行Android C高级编程时,一种常见的用途是开发游戏。使用C或C++编写游戏代码可以获得更好的性能和更低的延迟,这对于游戏的流畅运行至关重要。 此外,开发者还可以使用NDK为现有的Java应用程序添加本地本地扩展。这样可以通过使用C或C++编写某些关键组件,以改进应用程序的性能或添加新的功能。 总的来说,通过使用NDK进行Android C高级编程,开发者可以获得更高的性能、更好的控制权和更好的资源利用。无论是开发游戏还是优化应用程序,使用NDK都是提高性能和扩展功能的好方法。通过阅读相关的PDF文档,开发者可以更深入地了解如何使用NDK进行Android C高级编程。 ### 回答3: Android NDK (Native Development Kit) 是一个用于开发 Android 应用程序的工具集,它使开发者能够使用 C 或 C++ 编写原生代码,并将其与 Java 编写的 Android 应用程序一起使用。使用 NDK 可以达到增加性能、复用现有的 C/C++ 代码以及访问底层硬件等目的。 在 Android C 高级编程中,使用 NDK 商用 PDF 库可以实现在 Android 应用程序中处理 PDF 文件的功能。PDF 文件是一种常见的电子文档格式,使用 PDF 库可以读取、编辑和生成 PDF 文件。 使用 NDK 进行 PDF 处理的一般步骤如下: 1. 集成 PDF 库:首先,需要将商用的 PDF 库 (.so 文件) 集成到 Android 项目中。可以通过在 Android.mk 文件中添加相关配置,确保 .so 文件正确地被编译和链接到应用程序中。 2. 创建 JNI 接口:为了在 Java 层与 C/C++ 层之间进行通信,需要创建 JNI (Java Native Interface) 接口。可以在创建 JNI 方法时使用 JNAerator 或者手动编写 JNI 代码,以便在 Java 层调用 C/C++ 的功能。 3. 对 PDF 文件进行处理:在 C/C++ 层,可以使用 PDF 库提供的功能来处理 PDF 文件。例如,可以使用库提供的函数来解析、渲染、添加标注、提取内容等。 4. 将数据返回给 Java 层:在 C/C++ 层处理完之后,可以通过 JNI 接口将处理后的数据返回给 Java 层。这样就可以在 Android 应用程序中显示或者存储处理后的 PDF 文件。 需要注意的是,在使用商用 PDF 库时,需要遵循相关的许可协议,并确保在开发和分发过程中合法使用该库。 总之,通过使用 NDK 和商用 PDF 库,可以使 Android 应用程序具有处理 PDF 文件的高级编程能力。同时,开发者需要具备 C/C++ 编程和 JNI 接口的使用经验,以便顺利地进行开发工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值