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

什么是进程?C语言

进程的概念

进程就是执行中的程序,是系统资源分配的最小单位。

进程的内存分配

进程的作用

宏观上是并行的,微观上是串行的

进程的状态

对于基本的操作系统:有三个状态: 就绪态->执行态-> 阻塞态

在LInux中有四种:运行态,睡眠态,僵尸态,暂停态。

进程基本的函数

#include <unistd.h>             //fork()函数的头文件

fork( )

一次调用,会返回两次。
子进程先运行和是父进程先进程,顺序不确定。
变量不共享。
子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同。(同非常ID号子比父的要大一些)
功能:通过该函数可以从当前进程中克隆一个同名新进程。
          克隆的进程称为子进程,原有的进程称为 父进程。
          子进程是父进程的完全拷贝。
          子进程的执行过程是从fork函数之后执行。

返回值:
int 类型的数字
在父进程中 : 成功   返回值是子进程的pid号 > 0
            失败   返回-1
在子进程中: 成功    返回值0
               失败   无


getpid()

获得本进程的pid号

getppid()

获得父进程的pid号

父子进程的关系

子进程是父进程的副本。子进程获得父进程数据段,堆,栈,正文段共享。

进程的终止

8个情况
1)main 中return
2)exit(), c库函数,会执行io库的清理工作,关闭所有 的流,以及所有打开的文件。已经清理函数(atexit)。
3)_exit,_Exit 会关闭所有的已经打开的文件,不执行清理函数。
4) 主线程退出
5)主线程调用pthread_exit

异常终止
6)abort()
7)signal   kill pid
8)最后一个线程被pthread_cancle
 

注意:

exit(0  /  1 )  在使用的时候都是对的写 0 
                        存在错误的时候写            1

僵尸进程和孤儿进程

僵尸进程:一个主进程用fork创建了子线程,当子线程结束的时候,主线程没有调用wait或者waitpid回收掉这个子进程,这个子进程的任务描述符仍然在系统中。

孤儿进程:一个主进程用fork创建了子线程,主进程已经退出了,而子进程还在继续运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

进程操作示例代码:

1、创建两个线程:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>#include <sys/types.h>int main(int argc, char *argv[])
{pid_t pid = fork();               //用pid接受fork的返回值判断是父进程还是子进程if(pid>0){while(1){printf("fahter, 发送视频\n");sleep(1);}}else if(0 == pid){while(1){printf("child, 接收控制\n");sleep(1);}}else {perror("fork");return 1;}return 0;
}

2、对父子进程共用代码端的观察

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
int a = 10;
int main(int argc, char *argv[])
{pid_t pid = fork();if(pid>0){sleep(3);printf("father  a is %d\n",a);}else if(0 == pid){a+=20;printf("child  a is %d\n",a);}else {perror("fork");return 1;}printf("a is %d\n",a);return 0;
}//输出结果
child a is 30 
a is 30
father a is 10
a is 10

由此可知在父子进程中,在fork之前部分的代码为共用,而分进程之后进行的操作各自都会有自己的执行空间。

3、获得自己的pid和父进程的pid

 pid_t pid = fork();if(pid>0){sleep(3);printf("father  a is %d, pid:%d ppid:%d\n",a,getpid(),getppid());}else if(0 == pid){a+=20;printf("child  a is %d pid:%d ,ppid:%d\n",a,getpid(),getppid());}else {perror("fork");return 1;}

4、atexit //注册终止函数

调用了exit函数使进程终止退出,在进程终止之前,如果注册了终止函数,那么exit函数会先去依次调用进程终止函数,,每调用完一个终止函数并返回,调用顺序是以栈的形式来调用,调用flush刷新IO缓冲区的数据之后返回。

eg:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
char * tmp=NULL;
void clean(void)
{printf("this is clean %s\n",tmp);free(tmp);
}
int main(int argc, char *argv[])
{atexit(clean);tmp =(char*) malloc(50);strcpy(tmp,"hello");printf("123123\n");return 0;
}

输出结果为:

123123

this is clean  hello 


http://www.mrgr.cn/news/3026.html

相关文章:

  • Linux2.6设备驱动开发
  • Jmeter请求发送加密参数详解
  • Renumber程序——后面的想法没有实现
  • linux使用nginx部署springboot + vue分离项目
  • 【微信小程序】基础连接微信云数据库
  • 音视频相关知识
  • Nginx优化与防盗链
  • NoClassDefFoundError
  • 《区块链:能源市场变革的引领者》
  • 盒马鲜生源码开发
  • 杭州百腾教育科技 TiDB 6.5 to 7.5 升级记录
  • Day44 | 图论理论基础 98. 所有可达路径
  • Mycat分片-垂直拆分
  • 雨云美国二区E5v2服务器测评(非广告)
  • MySQL中处理JSON数据一文即可入门
  • 【图解秒杀系列】秒杀技术点——秒杀按钮点亮、削峰
  • 【无人驾驶】坐标变换和点云配准
  • Hadoop之DataNode启动源码解析
  • vue3 组合式 API:setup()
  • Java语言程序设计——篇十五(3)