进程和进程通信编程

死在山野的风里,活在自由的梦里

进程和进程通信编程

    • 进程基本操作编程
      • 完成下列程序运行,理解创建进程的系统调用并分析fork()与vfork()异同。
      • 实现一个程序启动另一个程序后自身仍然在运行,即在子进程中加载执行其他程序而父进程等待子进程结束后才结束。参考程序如下:**23-1.c**
    • 进程间通信编程
      • 编写一段C语言程序使其完成:父子进程通过无名管道传递三条消息:**23-2.c**
      • 利用Linux/UNIX的软中断信号,编写一段C语言程序完成:显示数字1到100,在程序运行中如果捕获到一个SIGINT信号,则转去执行一段显示当前系统时间的程序。在编程中要考虑到信号被复位 **(就是ctrl+c不再是调用另一个函数了,是恢复原来的退出功能)** 的情况,使程序能够实现多次被打断却多次的恢复执行。
    • 学习通作业
      • 1.父进程创建两个子进程,每个进程都在屏幕上显示自己的进程ID号,并在第1个子进程中加载执行一条外部命令。
      • 2.父进程创建1个子进程,然后建立无名管道与子进程互相传递问候信息(父进程发出“hello!”,子进程发出“Hi!”),最后各自将接收到的信息输出到屏幕。

本专栏参考教材是四川轻化工大学陈年老师的linux实验指导手册(含学习通的一些程序笔记)。
1、实验目的

掌握Linux环境下进程和进程间通信的概念、相关系统调用使用、多进程编程基本方法,初步掌握进程间通信的主要方式与编程方法。

2、实验工具及环境

Linux系统网络环境或单机,C编译环境。

3、实验计划学时

4学时上机实际操作。

4、实验内容及操作步骤

进程基本操作编程

完成下列程序运行,理解创建进程的系统调用并分析fork()与vfork()异同。

23-4.c

vfork()可让子进程先运行

#include 
#include 
#include 
#include 
#include 

int main(void)
{
    int data = 0;
    pid_t pid;
    int choose = 0;
    while ((choose = getchar()) != 'q')
    {
        switch (choose)
        {
        case '1':

            pid = fork();
            if (pid < 0)
            {
                printf("Error !\n");
            }

            if (pid == 0)
            {
                data++;
                exit(0);
            }

            wait(NULL);
            if (pid > 0)
            {
                printf("data is %d\n", data);
            }
            break;

        case '2':

            pid = vfork();
            if (pid < 0)
            {
                perror("Error !\n");
            }

            if (pid == 0)
            {
                data++;
                exit(0);
            }

            wait(NULL);

            if (pid > 0)
            {
                printf("data is %d\n", data);
            }
            break;

        default:

            break;
        }
    }
}

实现一个程序启动另一个程序后自身仍然在运行,即在子进程中加载执行其他程序而父进程等待子进程结束后才结束。参考程序如下:23-1.c

// 实现一个程序启动另一个程序后自身仍然在运行,即在子进程中加载执行其他程序而父进程等待子进程结束后才结束
#include 
#include 
#include 
#include 
#include 
#include 

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

{

    /*接受键盘输入命令字符*/

    pid_t pid;    
    pid = fork(); /*创建子进程*/

    if (pid < 0)
    {
        printf("创建失败");
    }

    else if (pid == 0)
    {
        sleep(1);
        execl("/bin/pwd", "pwd", NULL);
    }

    else
    {
        /*等待子进程信息*/

        int status;
        wait(&status);

        /*继续父进程的执行*/
        if (WIFEXITED(status) == 1) 
        {
            printf("ha ha\n");
        }
    }
}      

进程间通信编程

编写一段C语言程序使其完成:父子进程通过无名管道传递三条消息:23-2.c

·管道文件的测试程序开始

·管道文件测试正在进行

·管道通信测试结束

接收进程收到信息后将它们送到标准输出文件上。

// 编写一段C语言程序使其完成:父子进程通过无名管道传递三条消息:

#include        //用于main函数
#include 
#include     //用于pid_t
#include 
#include 

#include  //用于close,read,write,fork
#define BUFFSIZ sizeof("管道文件的测试程序开始")

int main() 
{
  char message[3][BUFFSIZ] = {"管道文件的测试程序开始", "管道文件测试正在进行","管道通信测试结束"};
  int i;
  int fd[2];                   //定义管道两端的描述符,有两个
  pipe(fd);                    //创建管道
  // printf("fd[0]:%d\n", fd[0]); //打印读端的fd
  // printf("fd[1]:%d\n", fd[1]); //打印写端的fd

  pid_t pid; //定义一个pid来接收fork的返回值
  pid = fork();

  if (pid < 0)
  {
      printf("创建失败");
      exit(2);
  }

  //父进程
  if (pid > 0)
  {
      close(fd[0]);
      for (i = 0; i < 3; i++)
      {
          sleep(1);
          if (write(fd[1], message[i], BUFFSIZ) != -1)
          {
              printf("message sent by parent:[%s]\n", message[i]);
              fflush(stdout);
          }
          else
          {
              printf("写入错误");
              exit(5);
          }
      }
  }

  //子进程
  if (pid == 0)
  {
      close(fd[1]);
      for (i = 0; i < 3; i++)
      {
          if (read(fd[0], message[i], BUFFSIZ) != -1)
          {
              printf("message received by child:[%s]\n", message[i]);
              fflush(stdout);
          }
          else
          {
              printf("读出错误");
              exit(4);
          }
      }
  }
}

利用Linux/UNIX的软中断信号,编写一段C语言程序完成:显示数字1到100,在程序运行中如果捕获到一个SIGINT信号,则转去执行一段显示当前系统时间的程序。在编程中要考虑到信号被复位 (就是ctrl+c不再是调用另一个函数了,是恢复原来的退出功能) 的情况,使程序能够实现多次被打断却多次的恢复执行。

23-3.c

// 利用Linux / UNIX的软中断信号,编写一段C语言程序完成:显示数字1到100,在程序运行中如果捕获到一个SIGINT信号,
// 则转去执行一段显示当前系统时间的程序。在编程中要考虑到信号被复位的情况,使程序能够实现多次被打断却多次的恢复执行。

#include 
#include 
#include 
#include 
#include 

#include 
#include 


void fun(int sig){
    if(sig==SIGINT){
        time_t sec = time(NULL);

        struct tm t = *localtime(&sec);

        printf("当前时间:%d:%d:%d\n", t.tm_hour, t.tm_min, t.tm_sec);
    }
}

int main(int argc, char *argv[])
{
    int i;
    signal(SIGINT, fun); //执行新的函数
    
    for(i=1;i<10;i++)
    {
        sleep(1);
        printf("i:%d\n",i);
    }
}

学习通作业

1.父进程创建两个子进程,每个进程都在屏幕上显示自己的进程ID号,并在第1个子进程中加载执行一条外部命令。

23-5.c

#include 

#include 

#include 

#include 
int main()

{

    pid_t pid;

    pid = fork();

    if (pid < 0)

    {

        printf("创建失败");

    }



    //父进程

    if (pid > 0)

    {

        printf("这是父进程,其pid为%d\n", getpid());



        sleep(1); //让子进程1先输出

        pid_t pid2;

        pid2 = fork();

        if (pid2 == 0)

        {

            printf("这是子进程2,其pid为%d,", getpid());

            printf("其父进程pid为%d\n", getppid());    

        }

        sleep(1); //让父进程运行慢一点,不要让子进程2的ppid变成1

    }



    //子进程

    if (pid == 0)

    {

        printf("这是子进程1,其pid为%d,", getpid());

        printf("其父进程pid为%d\n", getppid());    

        execl("/bin/pwd", "pwd", NULL);         //执行外部命令

    }

}

2.父进程创建1个子进程,然后建立无名管道与子进程互相传递问候信息(父进程发出“hello!”,子进程发出“Hi!”),最后各自将接收到的信息输出到屏幕。

23-6.c

#include  //用于main函数
#include 
#include  //用于pid_t
#include 
#include 

#include  //用于close,read,write,fork

int main() //不含参数
{
    char buf[32] = {0};

    int fd[2];                   //定义管道两端的描述符,有两个
    pipe(fd);                    //创建管道
    printf("fd[0]:%d\n", fd[0]); //打印读端的fd
    printf("fd[1]:%d\n", fd[1]); //打印写端的fd

    pid_t pid; //定义一个pid来接收fork的返回值
    pid = fork();

    if (pid < 0)
    {
        printf("创建失败");
    }

    //父进程
    if (pid > 0)
    {

        write(fd[1], "hello", 5);
        
        sleep(2);
      
        read(fd[0], buf, 32);
        printf("父进程收到:%s\n", buf);
      
    }

    //子进程
    if (pid == 0)
    {       
        read(fd[0], buf, 32);
        printf("子进程收到:%s\n", buf);      

        sleep(1);        
        write(fd[1], "hi", 2);
    }
}

你可能感兴趣的:(linux实验,linux,信息与通信,信号处理,c语言)