进程相关的概念

程序和进程

程序:二进制文件、占用磁盘空间

进程:运行着的程序,数据在内存中,占用系统资源,CPU,物理内存()

PCB描述进程(进程控制块)

把描述进程的所有信息的那条记录叫做 PCB(process control block)

每个进程有且仅有一个PCB

linux下的PCB:task_struct

存放在/usr/src/kernels/2.6.32-431.el6.i686/include/linux/sched.h

程序计数器:程序中即将被执行的下一条指令的地址。

内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块指针

进程优先级

优先级:相对于其他进程的优先级。

ps -al  #可查看进程优先级
renice -5 -p PID #修改进程优先级
#top命令可以实时动态地查看系统的整体运行情况

进程的五种状态

  1. R 运行 (正在运行或在运行队列中等待)

  2. S 中断 (休眠中, 受阻, 在等待某个条件的形成或接受到信号)

  3. D 不可中断 (收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)

  4. Z 僵死 (进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放)

  5. T 停止 (进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行)

并行和并发

并行:指两个或者多个事件在同一时刻发生;

并发:指两个或多个事件在同一时间间隔发生

孤进程和僵进程

孤儿进程:父进程先退出,子进程就称之为“孤儿进程”

僵尸进程:当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵进程。

僵尸进程放弃了几乎所有的内存空间,没有任何可执行代码,也不能别调度,

仅仅在进程列表保留位置,而且不占用任何内存空间

ps/kill命令的使用

ps -aux     #列出进程详细信息,可配合grep筛选

kill 1234 #杀死指定PID的进程

fork/getpid/getppid函数的使用

fork函数,计算机程序设计中的分叉函数

若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记;否则,出错返回-1

getpid返回当前进程标识,getppid返回父进程标识。

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

int main(void)
{
pid_t pid=fork();
switch(pid)
{
case -1:
printf("Fork Error\n");
case 0:
printf("\nI'm Child My PID=%d\n",getpid());
printf("My Parent PID=%d\n",getppid()); //这个父进程的父进程
printf("Child is Exiting\n");
exit(0);
default:
printf("\nI'm Parent My PID=%d\n",getpid());
printf("My Child PID is %d\n",pid);
}
}

execl/execlp函数的使用

Fork炸弹

这条命令在Linux shell下运行会让系统死机

具体意义百度百科上有

execl/execlp函数的使用

execl()函数:执行文件函数

表示后边的参数以可变参数的形式给出且都以一个空指针结束

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
   printf("entering main process---\n");
   execl("/bin/ls","ls","-l",NULL);
   printf("exiting main process ----\n");
   return 0;
}

利用execl将当前进程main替换掉,最后那条打印语句不会输出

execlp()函数:从PATH环境变量中查找文件并执行

第一个参数path不用输入完整路径,给出命令名即可,它会在环境变量PATH当中查找命令

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
   printf("entering main process---\n");
   execlp("ls","ls","-l",NULL);
   printf("exiting main process ----\n");
   return 0;
}

wait函数和waitpid函数的使用

wait()函数用于使父进程(也就是调用wait()的进程)阻塞,

直到一个子进程结束或者该进程接收到了一个指定的信号为止。

如果该父进程没有子进程或者它的子进程已经结束,则wait()函数就会立即返回。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t pid,pw;
pid=fork();
if(pid<0)
{
puts("fork eorro!\n");
exit(1);
}
else if(pid==0) //子进程
{
printf("I'm Child,pid=%d\n",getpid());
sleep(5);
exit(0);
}
else
{
pw=wait(NULL);
printf("I catch a Child,PID is %d\n",pw);
}
exit(0);
}

系统调用exit后,该进程并非马上消失,而是留下一个叫僵尸进程的数据结构

waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程(它可以指定需要等待终止的子进程)

它还有若干选项,如可提供一个非阻塞版本的 wait()功能,也能支持作业控制。

实际上,wait()函数只是 waitpid()函数的一个特例,在Linux 内部实现 wait()函数时直接调用的就是waitpid()函数

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
  pid_t pc,pr;
  pc=fork();
  if (pc<0)/* fork错误*/
  {
      printf("fork error\n");
      exit(1);
  }
  else if(pc==0)/*在子进程中*/
  {
      sleep(5);
      exit(0);
  }
  else
  {
      do {/* 使用了WNOHANG参数,waitpid不会在这里等待 */
          pr=waitpid(pc,NULL,WNOHANG);
          if (pr==0)
          {
              printf("No child exit\n");
              sleep(1);
          }
        }while (pr==0);
      if (pr==pc)
          printf("successfully get child %d\n",pr);
      else
          printf("wait child error\n");
  }
  return 0;
}

Linux-c系统编程的更多相关文章

  1. 《Linux/Unix系统编程手册》读书笔记 目录

    <Linux/Unix系统编程手册>读书笔记1  (创建于4月3日,最后更新4月7日) <Linux/Unix系统编程手册>读书笔记2  (创建于4月9日,最后更新4月10日) ...

  2. 《Linux/Unix系统编程手册》读书笔记9(文件属性)

    <Linux/Unix系统编程手册>读书笔记 目录 在Linux里,万物皆文件.所以文件系统在Linux系统占有重要的地位.本文主要介绍的是文件的属性,只是稍微提及一下文件系统,日后如果有 ...

  3. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

  4. 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

    <Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...

  5. 《Linux/Unix系统编程手册》读书笔记6

    <Linux/Unix系统编程手册>读书笔记 目录 第9章 这章主要讲了一堆关于进程的ID.实际用户(组)ID.有效用户(组)ID.保存设置用户(组)ID.文件系统用户(组)ID.和辅助组 ...

  6. 《Linux/Unix系统编程手册》读书笔记5

    <Linux/Unix系统编程手册>读书笔记 目录 第8章 本章讲了用户和组,还有记录用户的密码文件/etc/passwd,shadow密码文件/etc/shadow还有组文件/etc/g ...

  7. 《Linux/Unix系统编程手册》读书笔记4

    <Linux/Unix系统编程手册>读书笔记 目录 第7章: 内存分配 通过增加堆的大小分配内存,通过提升program break位置的高度来分配内存. 基本学过C语言的都用过mallo ...

  8. 《Linux/Unix系统编程手册》读书笔记3

    <Linux/Unix系统编程手册>读书笔记 目录 第6章 这章讲进程.虚拟内存和环境变量等. 进程是一个可执行程序的实例.一个程序可以创建很多进程. 进程是由内核定义的抽象实体,内核为此 ...

  9. 《Linux/Unix系统编程手册》读书笔记1

    <Linux/Unix系统编程手册>读书笔记 目录 最近这一个月在看<Linux/Unix系统编程手册>,在学习关于Linux的系统编程.之前学习Linux的时候就打算写关于L ...

  10. 《Linux/Unix系统编程手册》读书笔记2

    <Linux/Unix系统编程手册>读书笔记 目录 第5章: 主要介绍了文件I/O更深入的一些内容. 原子操作,将一个系统调用所要完成的所有动作作为一个不可中断的操作,一次性执行:这样可以 ...

随机推荐

  1. Python 内置函数---map()

    描述 map() 实现对一个可迭代对象中的每一个元素都应用一个函数 将被传入的函数作用到一个可迭代对象的每一个元素上,并且返回了包含了所有这些函数调用结果的一个迭代器. 由于map期待传入一个函数并会 ...

  2. bzoj千题计划241:bzoj3864: Hero meet devil

    http://www.lydsy.com/JudgeOnline/problem.php?id=3864 题意: 给你一个DNA序列,求有多少个长度为m的DNA序列和给定序列的LCS为0,1,2... ...

  3. 使用 maven 搭建web开发基本架构

    我觉得可能,对于还没有使用过 IDEA 进行开发的童鞋来说,直接撸代码是有些尴尬的.那么我会把示例代码之前的那些事再在这里写一遍 按图步骤进行即可进行基本项目结构搭建 现在基本流行 maven 管理项 ...

  4. html5 canvas从圆开始

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Flex 经验笔记二

    向 Module 传递数据:好像只能传递些像 整型,字符型等简单类型的数据,也能传递像 json 这样的 Object 对象,但如果 Object 对象是从层的,其子级数据,好像也读取不到. func ...

  6. BAT修改文本内容

    @echo off (for /f "delims=" %%a in (文件名) do ( set "str=%%a" setlocal enabledelay ...

  7. 在 Linux 上找出并解决程序错误的主要方法【转】

    转自:https://www.ibm.com/developerworks/cn/linux/sdk/l-debug/index.html 本文讨论了四种调试 Linux 程序的情况.在第 1 种情况 ...

  8. jenkins执行构建任务报错之java.lang.NoSuchFieldError: DEFAULT_USER_SETTINGS_FILE

    在执行创建工作空间时候,创建不成功,出现错误?? ......... java.lang.NoSuchFieldError: DEFAULT_USER_SETTINGS_FILE ......... ...

  9. 一个查看Access数据库密码的工具

    一个可以查看Access数据库密码的工具AccessCracker.需要.net2.0环境支持. 网盘地址:https://pan.baidu.com/s/1btbsFcsKO0Enj-rjkTlz6 ...

  10. 集合类List、Set、Map的区别、联系和遍历方式

    说集合之前,先说说数组和集合: 1.数组长度是固定的,当超过容量后会在内存中重新创建一个原来数组1.5倍长度的新数组,再把元素存进去:数组既可以存储基本数据类型,又可以存储引用数据类型. 2.集合长度 ...