上篇文章了解到Linux平台下编译静态库和动态库并了解到链接的原理。https://www.jianshu.com/p/020b341d3c2b 这篇文章来了解一些进程方面的知识。
进程是程序运行的活动,是系统进行资源分配和调度的基本单位。简单的来看一个正在运行的程序就是一个进程。进程包含的数据有程序可运行机器码映像。映像加载到虚拟内存的 。内存的内容包括可运行代码、特定于进程的数据(输入、输出)、调用堆栈、堆栈(用于保存运行时运数中途产生的数据)。 分配给该进程的资源的操作系统描述符,如文件描述或文件句柄等。进程也类似线程存在状态的,由内核pcb进程控制块来控制进程的状态。
进程之间通信
为了安全系统设计进程之间的数据是不可以共享的,有时又需要访问另一个进程的数据。就需要进程之间的通信。
利用管道通信:
管道可以看成是一个特殊的文件,它不占磁盘空间,占用的是内存,所以我们直接可以read 和write数据。由于管道是半双工数据传输,数据只能单向流通,读写数据是不能够同时进行的。而且只限于有血缘关系(父子,兄弟进程)的进程之间的通信。
通过fork函数创建子线程看看他们是怎么通信的。
#include<stdio.h>
#include<unistd.h>
//父进程向子线程 写东西
int main() {
int fd[2];
int ret = pipe(fd);
if(ret != 0) {
printf("crate pipe fail\n");
return -1;
}
pid_t pid = fork();
if(pid < 0) {
printf("fork process fail\n");
return -1;
} else if(pid == 0){
sleep(2);
printf("Im child process\n");
close(fd[1]);
char buf[11];
read(fd[0],buf,11);
printf("输出:%s",buf);
}else{
printf("Im parent process\n");
close(fd[0]);
write(fd[1],"hello world",11);
}
return 0;
}
信号:
进程之间可以通过信号来进行通信,信号是内核自带的传递携带数据量不大,一般携带一个数字作为处理的信号。在pcb进程控制块中包含有信号屏蔽字与未决信号集。信号的产生有系统调用kill , raise, abort等函数,包括硬件的异常,访问了非法内存等都会产生信号。信号的处理方式,系统可以忽略 捕获 执行系统默认活动,android应用出现异常退出系统接收到信息执行了默认的活动程序才退出的。包括进程的杀死的都是通过系统接收信号来执行的。pcb进程控制块中的信号屏蔽字是用来屏蔽某个型号的,一个型号发送是发送到pcb进程控制块中的未决信号集中的,系统执行信号时需要查看该信号是否屏蔽。
共享映射区:
看看具体的代码实现
写端
#include<stdio.h>
#include<unistd.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<string.h>
int main() {
int fd = open("mmapipc",O_RDWR | O_CREAT | O_TRUNC, 0644);
ftruncate(fd, 13);
if(fd == -1) {
printf("open fail \n");
return -1;
}
char* writecontent =(char*) mmap(NULL,13,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(writecontent == MAP_FAILED) {
printf("映射失败");
return -1;
}
while(1){
sleep(1);
memcpy(writecontent, "hello", 5);
}
return 0;
}
读端
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/mman.h>
#include <fcntl.h>
int main(){
char *pathname = "mmapipc";
int fd = open(pathname,O_RDONLY);
if(fd == -1) {
printf("open file fail\n");
return -1;
}
char* readIpc =(char*)mmap(NULL,11,PROT_READ, MAP_SHARED, fd, 0);
if(readIpc == MAP_FAILED) {
printf("open file fail\n");
return -1;
}
while (1){
printf("%s",readIpc);
}
return 0;
}
小结:
Linux进程之间的通信还有套接字的方式,这里不去了解,关于进程知识,包括怎么fork子进程,什么是孤儿进程,僵尸进程,守护进程,包括虚拟内存有兴趣可以了解了解。