当你回答进程时你应该回答什么?

  1. 什么是进程?
    它是运行中的程序,一个程序可以有多个进程,进程包含程序计数器(用来存放下一条指令存放的地址)、寄存器(用来存储指令,数据和地址)、变量当前的值。
  2. 进程如何创建?
    可以通过系统调用来创建子进程,fork().
    pid_t pd;
    pd=fork();

    该系统调用创建了一个子进程,该子进程拥有与父进程一样的初始状态,PCB相同,用户态代码也相同,数据也相同。此时刚调用完fork()函数,还没有返回,至于先返回子进程还是先返回父进程要看系统调度策略。
    子进程中fork()的返回值是0;父进程中fork()的返回值是子进程的进程号,如果创建失败返回-1。子进程可以通过getpid()获得自己的进程号。
    进程创建之后拥有独立的地址,对数据的修改,对方是看不见的,但是双方可以共享打开文件之类的资源,通过共享内存的方式通信是进程通信的一种方式。进程只有一个父进程,可以有多个子进程。
    终端输入PS可以看见当前正在运行的进程。

  3. 进程的终止
    终止方式有:
    1. 正常退出,exit()系统调用用来通知系统进程结束;
    2. 出错退出;
    3. 严重错误;
    4. 被其他进程杀死。
  4. 进程的状态
    就绪态,运行态,阻塞态。
    就绪态是进程可以运行,但是需要等待系统调用,一旦被系统调用就进入运行态;运行态是进程被系统调用,当分时片用完之后,系统就会由回到就绪态,系统会调用别的处在就绪状态的进程;阻塞态是进程在运行时,等待某一外部条件发生,而被阻塞,如果条件到达,进程就进入就绪态,等待系统再次调用。
  5. exec函数
    前面fork()创建的子进程执行的还是父进程的函数,可以系统调用exec()以执行另一程序。
  6. wait()和waitpid()函数
    当一个进程终止时会关闭所有文件描述符,占有的内存,但PCB还保留着,里面保留着进程退出的信息,如果是正常退出,则保存着退出状态,如果是异常退出,则保存着导致该进程异常退出的信号,wait()和waitpid()用于获取这些信息,然后清理该进程。如果一个进程已经终止,但是父进程没有对其进行清理,那么这个进程就会成为僵尸进程。ps u命令可以查看进程状态,记录带有<defunct>就是僵尸进程。
    pid_t wait(int *status);
    pid_t wait_pid(pid_t pid,int *status,int options);

    如果调用成功,返回子进程的进程号;如果调用失败,返回-1。
    父进程调用该函数有三种情况:
    父进程阻塞(子进程还在运行);
    带上子进程信息返回(子进程执行完毕);
    出错立即返回(没有子进程)。
    两个函数的区别:
    wait()函数的调用,如果子进程还在执行,那么父进程会阻塞;
    wait_pid()函数的调用,若指定options为WNOHANG,则父进程不会阻塞而立即返回0。
    wait()等待第一个子进程结束,wait_pid()可以指定等待子进程。
     

    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
    	pid_t pid;
    	pid = fork();
    	if (pid < 0) {
    		perror("fork failed");
    		exit(1);
    	}
    	if (pid == 0) {
    		int i;
    		for (i = 3; i > 0; i--) {
    			printf("This is the child\n");
    			sleep(1);
    		}
    		exit(3);
    	} else {
    		int stat_val;
    		waitpid(pid, &stat_val, 0);
    		if (WIFEXITED(stat_val))
    			printf("Child exited with code %d\n", WEXITSTATUS(stat_val));
    		else if (WIFSIGNALED(stat_val))
    			printf("Child terminated abnormally, signal %d\n", WTERMSIG(stat_val));
    	}
    	return 0;
    }

     

  7. 进程间通信的方式
    首先必须明白进程间通信是什么?
    两个进程,由于相互独立,因此如果要通信,就应该在内核区开辟空间,一个进程从用户态进入内核,将数据存入内核区,另一个进程从该内核区取数据,内核提供这种通信方式叫进程间通信,IPC(InterProcess  Communication)。
     

    管道通信,消息队列,FIFO,信号量,共享内存,socket套接字。

    1. 管道通信
       

      #include <unistd.h>
      int pipe(int fileds[2]);
      该函数在内核中开辟一段缓冲区用于通信,管道就是这段缓冲区,该缓冲区有两个端口:
      读端和写端,它们的文件描述符存在fileds[2]中,fileds[0]是读端,fileds[1]是写端
      read(fileds[0]);
      write[fileds[1]);
      
      管道创建成功返回0,创建失败返回-1.

      父进程创建管道,fork()创建子进程,子进程通过文件描述符读写数据;父进程还可以创建两个子进程,将文件描述符传给两个子进程,这样两个子进程就能通信了。父进程与子进程通过管道通信的方式如下:
       

      #include <sys/types.h>
      #include <sys/wait.h>
      #include <unistd.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <iostream>
      #include <string.h>
      #define MAXSIZE 100
      int main(void)
      {
          pid_t pid;
          int fd[2];
          int er=pipe(fd);
          if(er==-1){
              perror("fail to create pipe");
              exit(1);
          }
          char buffer[MAXSIZE];
          pid = fork();
          if (pid < 0) {
              perror("fork failed");
              exit(1);
          }
          if (pid == 0) {
              close(fd[1]);
              read(fd[0],buffer,MAXSIZE);
              std::cout<<buffer<<std::endl;
              exit(3);
          } else {
              close(fd[0]);
              std::string str="liujinyang";
              write(fd[1],&str,str.length()+1);
              wait(NULL);
          }
          return 0;
      }

      注意:通过管道通信时,必须有一方关闭写文件描述符,另一端关闭读文件描述符,也就是,单工通信。上面是只能父进程写,子进程读;如果同时需要子进程写,父进程读,那么还需要建立一个管道。
      使用管道需要注意以下四种情况:

      1. 管道为空,如果写端没有关闭,继续读会导致阻塞,直到有数据;如果写端关闭,返回0。

      2. 管道满,如果读端关闭,继续写会产生SIGPIPE信号,导致进程异常终止;如果读端未关闭,继续写,会阻塞;

    2. 其他的不想写了,socket通信有一个专门的博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值