嵌入式技术及应用-【Ubuntu】实验4-linux应用开发实验

1.编写多进程程序,该实验有3个进程,其中一个为父进程,其余两个是该父进程创建的子进程,其中一个子进程运行“ls -l”指令,另一个子进程在暂停5s之后异常退出,父进程先用阻塞方式等待第一个子进程的结束,然后用非阻塞方式等待另一个子进程的退出,等待收集到第二个子进程结束的信息,父进程就返回。实验流程图如图4.1所示。

lab431.c源码:

//此处命名为lab431.c

  /* multi_proc_wrong.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
	pid_t child1, child2, child;
         /* 创建两个子进程 */
         child1 = fork();
         child2 = fork();
         /* 子进程1的出错处理 */
         if (child1 == -1)
         {
             printf("Child1 fork error\n");
             exit(1);
         }
         /* 在子进程1中调用execlp()函数 */
         else if (child1 == 0)
         {
             printf("In child1: execute 'ls -l'\n");
             if (execlp("ls", "ls", "-l", NULL) < 0)
             {
                 printf("Child1 execlp error\n");
             }
         }

         /* 子进程2的出错处理 */
         if (child2 == -1)
         {
             printf("Child2 fork error\n");
             exit(1);
         }
         /* 在子进程2中使其暂停5s */
         else if( child2 == 0 ) 
        {
             printf("In child2: sleep for 5 seconds and then exit\n");
             sleep(5);
             exit(0);
         }
         /* 在父进程中等待两个子进程的退出 */
         else 
        {
             printf("In father process:\n");
             child = waitpid(child1, NULL, 0); /* 阻塞式等待 */
             if (child == child1)
             {
                 printf("Get child1 exit code\n");
             }
             else
             {
                 printf("Error occured!\n");
             }

             do
             {
                 child = waitpid(child2, NULL, WNOHANG);/* 非阻塞式等待 */
                 if (child == 0)
                 {
                     printf("The child2 process has not exited!\n");
                     sleep(1);
                 }
             } while (child == 0);

             if (child == child2)
             {
                 printf("Get child2 exit code\n");
             }
             else
             {
                 printf("Error occured!\n");
             }
         } 
        exit(0);
} 


lab432.c源码:

/* multi_proc.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
	pid_t child1, child2, child;

         /* 创建两个子进程 */
         child1 = fork(); 
        /* 子进程1的出错处理 */
         if (child1 == -1)
         {
             printf("Child1 fork error\n");
             exit(1);
         }
         /* 在子进程1中调用execlp()函数 */
         else if (child1 == 0) 
         {
             printf("In child1: execute 'ls -l'\n");
             if (execlp("ls", "ls", "-l", NULL) < 0)
             {
                 printf("Child1 execlp error\n");
             }
         }
         /* 在父进程中再创建进程2,然后等待两个子进程的退出 */
         else
         {
             child2 = fork();
             /* 子进程2的出错处理 */
             if (child2 == -1)
             {
                 printf("Child2 fork error\n");
                 exit(1);
             }
             /* 在子进程2中使其暂停5s */
             else if(child2 == 0)
             {
                 printf("In child2: sleep for 5 seconds and then exit\n");
                 sleep(5);
                 exit(0);
             }
//hcy1031
              else 
             {
             printf("In father process:\n");
             child = waitpid(child1, NULL, 0); /* 阻塞式等待 */
             	if (child == child1)
             	{
                 	printf("Get child1 exit code\n");
             	}
             	else
             	{
                 	printf("Error occured!\n");
             	}
             	do
             	{
                 	child = waitpid(child2, NULL, WNOHANG);/* 非阻塞式等待 */
                 	if (child == 0)
                	{
                     	printf("The child2 process has not exited!\n");
                     	sleep(1);
                 }
             	} while (child == 0);

             	if (child == child2)
             	{
                 	printf("Get child2 exit code\n");
             	}
            	 else
             	{
                 	printf("Error occured!\n");
             	}
         } 
        exit(0);
     } 
}

2.编写有名管道多路通信程序,实验流程图如图4.2所示。

lab4_4.c源码:

   /* pipe_select.c */
     #include <fcntl.h>
     #include <stdio.h>
     #include <unistd.h>
     #include <stdlib.h>
     #include <string.h>
     #include <time.h>
     #include <errno.h>

     #define FIFO1 "in1"
     #define FIFO2 "in2"
     #define MAX_BUFFER_SIZE 1024 /* 缓冲区大小 */
     #define IN_FILES 3 /* 多路复用输入文件数目 */
     #define TIME_DELAY 60 /* 超时值秒数 */
     #define MAX(a, b) ((a > b)?(a):(b))

     int main(void)
     {
         int fds[IN_FILES];
         char buf[MAX_BUFFER_SIZE];
         int i, res, real_read, maxfd;
         struct timeval tv;
         fd_set inset,tmp_inset;

         fds[0] = 0; 

        /* 创建两个有名管道 */
         if (access(FIFO1, F_OK) == -1) 
        {
             if ((mkfifo(FIFO1, 0666) < 0) && (errno != EEXIST))
             {
                 printf("Cannot create fifo file\n");
                 exit(1);
             }
         }
         if (access(FIFO2, F_OK) == -1) 
        {
             if ((mkfifo(FIFO2, 0666) < 0) && (errno != EEXIST))
             {
                 printf("Cannot create fifo file\n");
                 exit(1);
             }
         }

         /* 以只读非阻塞方式打开两个管道文件 */
         if((fds[1] = open (FIFO1, O_RDONLY|O_NONBLOCK)) < 0)
         {
             printf("Open in1 error\n");
             return 1;
         } 
        if((fds[2] = open (FIFO2, O_RDONLY|O_NONBLOCK)) < 0)
         {
             printf("Open in2 error\n");
             return 1;
         }

         /* 取出两个文件描述符中的较大者 */
         maxfd = MAX(MAX(fds[0], fds[1]), fds[2]);
         /* 初始化读集inset,并在读文件描述符集中加入相应的描述集 */
         FD_ZERO(&inset); 
        for (i = 0; i < IN_FILES; i++)
         {
             FD_SET(fds[i], &inset);
         }
         FD_SET(0, &inset);

         tv.tv_sec = TIME_DELAY;
         tv.tv_usec = 0;
         // 循环测试该文件描述符是否准备就绪,并调用select()函数对相关文件描述符做相应操作
         while(FD_ISSET(fds[0],&inset) || FD_ISSET(fds[1],&inset) || FD_ISSET(fds[2], 
        &inset))
         { 
            /* 文件描述符集的备份,以免每次都进行初始化 */
             tmp_inset = inset; 
            res = select(maxfd + 1, &tmp_inset, NULL, NULL, &tv);
             switch(res)
             {
                 case -1:
                 {
                     printf("Select error\n");
                     return 1;
                 }
                 break; 
                case 0: /* Timeout */
                 {
                     printf("Time out\n");
                     return 1;
                 } 
                break; 
                default:
                 {
                     for (i = 0; i < IN_FILES; i++)
                     {
                         if (FD_ISSET(fds[i], &tmp_inset))
                         {
                             memset(buf, 0, MAX_BUFFER_SIZE);
                             real_read = read(fds[i], buf, MAX_BUFFER_SIZE);
                             if (real_read < 0)
                             {
                                 if (errno != EAGAIN)
                                 {
                                     return 1;
                                 }
                             }
                             else if (!real_read)
                             {
                                 close(fds[i]);
                                 FD_CLR(fds[i], &inset);
                             }
                             else
                             {
                                 if (i == 0)
                                 { /* 主程序终端控制 */
                                     if ((buf[0] == 'q') || (buf[0] == 'Q'))
                                     {
                                         return 1;
                                     }
                                 }
                                 else
                                 { /* 显示管道输入字符串 */
                                     buf[real_read] = '\0';
                                     printf("%s", buf);
                                 }
                             }
                         } /* end of if */ 
                    } /* end of for */
                 }
                 break; 
            } /* end of switch */ 
        } /* end of while */
         return 0;
     }

通过本次实验了解主机与开发板的连接和通信(包括串口和网络连接、主机与开发板之间的文件传输);掌握如何编写和编译Linux应用程序,并下载到开发板运行;通过编写多进程程序,熟练掌握fork()、exec()、wait()和waitpid()等函数的使用;通过编写有名管道多路通信实验,进一步掌握管道的创建、读写等操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

利威尔·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值