SylixOS 的system使用

1. 適用範圍

SylixOS是一款爲大型嵌入式系統設計的硬實時系統,支持使用system調用執行命令。SylixOS爲了保證明時性在system的實現上和Linux有所差異,本文着重介紹SylixOS如何實現system和在使用system時須要注意的事項。shell

2. 原理介紹

SylixOS爲保證系統的實時性因此沒有實現fork功能,Linux下system是使用fork實現的。而SylixOS則經過使用內核的shell線程實現system功能。app

2.1      Linux的system功能淺析

Linux下system會調用fork產生子進程,由子進程execve調用/bin/sh-c string來執行參數string字符串所表明的命令,此命令執行完後隨即返回原調用的進程。異步

由於Linux下是經過fork實現system,因此被執行的命令繼承父系的一些資源(好比文件描述符,父系的工做路徑等)。同時可以實現異步執行和同步執行,同步執行即父系等待system調用運行結束(包括system調用的命令執行結束);異步即不等待,父系繼續運行。函數

2.2     SylixOS的system原理介紹

#include <stdlib.h>spa

int system(const char  *command);線程

函數成功返回 0,失敗返回-1,並設置錯誤碼。設計

SylixOS的system是先建立一個內核的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調用現象ci

2.3      SylixOS的system功能

SylixOS 的system實現原理和Linux不一樣,功能上和Linux的基本相同。

1. SylixOS實現system基礎功能,調用執行命令;

2. SylixOS 的system執行命令可設置爲同步執行和異步執行。

3. SylixOS的system繼承父系進程的工做空間;

4. SylixOS中由system啓動的進程繼承內核線程的棧空間大小;

5.Linux的system調用的三者有血緣關係,因此被system調用的進程繼承父系的資源(包括文件描述符),而SylixOS的system調用的三者之間沒有血緣關係,因此不可以繼承父系的資源。因此SylixOS在使用system時須要注意,在技術實現章節會介紹如何實現system的這個功能。

3. 技術實現

在移植Linux應用程序時,在某些特定的場景上Linux用戶會在A進程經過system調用B進程,同時經過傳參把一些文件描述符傳遞到B進程。由於Linux下B進程繼承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)          /* 建立文件的權限              */

 

int main(int argc, 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>

int main (int argc, char **argv)

{

    int readfd;

    int writefd;

 

    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來替換system。posix_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)            /* 建立文件的權限               */

 

int main(int argc, 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_t iPid;

 

    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進程技術筆記》

相關文章
相關標籤/搜索