SylixOS 的system使用

本文详细介绍了SylixOS系统中system调用的实现原理及其与Linux环境下system调用的区别,针对SylixOS环境下无法直接继承父进程资源的问题,提供了使用posix_spawn替代system调用的技术方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 适用范围

      SylixOS是一款为大型嵌入式系统设计的硬实时系统,支持使用system调用执行命令。SylixOS为了保证实时性在system的实现上和Linux有所差别,本文着重介绍SylixOS如何实现system和在使用system时需要注意的事项。

2. 原理介绍

       SylixOS为保证系统的实时性所以没有实现fork功能,Linuxsystem是使用fork实现的。而SylixOS则通过使用内核的shell线程实现system功能。

2.1  Linux的system功能浅析

        Linuxsystem会调用fork产生子进程,由子进程execve调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。

因为Linux下是通过fork实现system,所以被执行的命令继承父系的一些资源(比如文件描述符,父系的工作路径等)。同时能够实现异步执行和同步执行,同步执行即父系等待system调用运行结束(包括system调用的命令执行结束);异步即不等待,父系继续运行。

2.2  SylixOS的system原理介绍

#include<stdlib.h>

intsystem(constchar  *command);

        函数成功返回 0,失败返回-1,并设置错误码。

        SylixOSsystem是先创建一个内核的shell线程,然后通过内核的shell线程执行system需要执行的命令。

如果使用system调用执行一个进程,则同时启动一个内核线程来join等待清除该进程。如果使用system调用执行一个shell命令,则直接由内核线程t_tshell负责清除。如图 2‑1所示,由open(pid=5)调用system执行hellow(pid=6),而内核创建一个hellow(pid=0)的内核线程join等待。

2‑1  system调用现象

23. SylixOS的system功能

       SylixOS system实现原理和Linux不同,功能上和Linux的基本相同。

1. SylixOS实现system基础功能,调用执行命令;

2. SylixOS system执行命令可设置为同步执行和异步执行。

3. SylixOSsystem继承父系进程的工作空间;

4. SylixOS中由system启动的进程继承内核线程的栈空间大小;

5.Linuxsystem调用的三者有血缘关系,所以被system调用的进程继承父系的资源(包括文件描述符),而SylixOSsystem调用的三者之间没有血缘关系,所以不能够继承父系的资源。所以SylixOS在使用system时需要注意,在技术实现章节会介绍如何实现system的这个功能。

3. 技术实现

       在移植Linux应用程序时,在某些特定的场景上Linux用户会在A进程通过system调用B进程,同时通过传参把一些文件描述符传递到B进程。因为LinuxB进程继承A进程的文件描述符,所以B进程便能使用A进程的文件描述符进行操作。

使用场景如程序清单 3‑1和程序清单 3‑2所示。

程序清单  3‑1  A进程代码

#include<stdio.h>

#include<stdlib.h>

 

#define PATH_LEN   20                                          /* 路径长度              */

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)  /* 创建文件的权限        */

 

intmain(intargc, char **argv)

{

    int   iFd1;

    int   iFd2;

    char  cBuf[PATH_LEN] = {0};

 

    iFd1 = open("test1", O_CREAT | O_WRONLY, FILE_MODE);                                 /* 打开文件                          */

    iFd2 = open("test2", O_CREAT | O_WRONLY, FILE_MODE);

 

    printf("open   readfd %d  writefd %d\n", iFd1, iFd2);

/*

* 构建system命令字符串    

*/

sprintf(cBuf, "%s %d:%d", "/apps/hellow/hellow", iFd1, iFd2);

 

    system(cBuf);                                             /* 调用system执行        */

 

    close(iFd1);

    close(iFd2);

    printf("after system!\n");

    return 0;

}

程序清单   3‑2  B进程代码

#include<stdio.h>

intmain (intargc, char **argv)

{

    intreadfd;

    intwritefd;

 

    sscanf (argv[1], "%d:%d", &readfd, &writefd);    /* 解析参数,获得文件描述符      */

    printf("hellow readfd %d  writefd %d\n", readfd, writefd);

 

    if (!write(writefd, "SylixOS", sizeof("SylixOS"))) {

        perror("write");

        return -1;

    }

    return  (0);

}

     在SylixOS运行结果如所示,B进程没有继承A进程的文件描述符导致报错。

3‑1  SylixOS运行结果

       遇到这种情况,可以通过使用posix_spawn来替换systemposix_spawn函数创建子进程并继承父系的文件描述符,所以可以通过posix_spawn替换system实现。如程序清单 3‑3所示,只需修改A进程,B进程不用修改。

程序清单  3‑3  A进程修改后源码

#include<stdio.h>

#include<stdlib.h>

#include<spawn.h>

 

#define PATH_LEN   20                                         /* 路径长度               */

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)  /* 创建文件的权限        */

 

intmain(intargc, char **argv)

{

    int   iFd1;

    int   iFd2;

    char  cBuf[PATH_LEN] = {0};

 

    iFd1 = open("test1", O_CREAT | O_WRONLY, FILE_MODE);                                 /* 打开文件                          */

    iFd2 = open("test2", O_CREAT | O_WRONLY, FILE_MODE);

 

    printf("open   readfd %d  writefd %d\n", iFd1, iFd2);

#ifndef SYLIXOS

/*

* 构建system命令字符串    

*/

    sprintf(cBuf, "%s %d:%d", "/apps/hellow/hellow", iFd1, iFd2);      

    system(cBuf);                                   /* 调用system执行              */

#else

    char  *pcArgv[5] = { "/apps/hellow/hellow", "SylixOS", (char *)0 };

    int   iRet;

    pid_tiPid;

 

    sprintf(pcArgv[1], "%d:%d", iFd1, iFd2);      /* 构建system命令字符串         */

    iRet = posix_spawn(&iPid,                       /*  启动进程                    */

                       "/apps/hellow/hellow",

                       NULL,

                       NULL,

                       pcArgv,

                       NULL);

    if (iRet != 0) {

       close(iFd1);

       close(iFd2);

       return (-3);

    }

#endif

    waitpid(iPid, NULL, 0);

    close(iFd1);

    close(iFd2);

    printf("after system!\n");

    return 0;

}

运行结果如图 3‑2所示,运行正确。

3‑2  修改后运行结果

4. 参考资料

SylixOS 应用开发手册》

TN0015_fork函数替换为SylixOS进程技术笔记》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值