首頁 > 軟體

SylixOS 的system使用

2020-06-16 17:12:52

1. 適用範圍

SylixOS是一款為大型嵌入式系統設計的硬實時系統,支援使用system呼叫執行命令。SylixOS為了保證實時性在system的實現上和Linux有所差別,本文著重介紹SylixOS如何實現system和在使用system時需要注意的事項。

2. 原理介紹

SylixOS為保證系統的實時性所以沒有實現fork功能,Linuxsystem是使用fork實現的。而SylixOS則通過使用核心的shell執行緒實現system功能。

2.1      Linuxsystem功能淺析

Linuxsystem會呼叫fork產生子進程,由子進程execve呼叫/bin/sh-c string來執行引數string字串所代表的命令,此命令執行完後隨即返回原呼叫的進程。

因為Linux下是通過fork實現system,所以被執行的命令繼承父系的一些資源(比如檔案描述符,父系的工作路徑等)。同時能夠實現非同步執行和同步執行,同步執行即父系等待system呼叫執行結束(包括system呼叫的命令執行結束);非同步即不等待,父系繼續執行。

2.2  SylixOSsystem原理介紹

#include<stdlib.h>

intsystem(constchar  *command);

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

SylixOSsystem是先建立一個核心的shell執行緒,然後通過核心的shell執行緒執行system需要執行的命令。

如果使用system呼叫執行一個進程,則同時啟動一個核心執行緒來join等待清除該進程。如果使用system呼叫執行一個shell命令,則直接由核心執行緒t_tshell負責清除。如圖 21所示,由open(pid=5)呼叫system執行hellow(pid=6),而核心建立一個hellow(pid=0)的核心執行緒join等待。

                        圖 21  system呼叫現象

2.3      SylixOSsystem功能

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進程的檔案描述符進行操作。

使用場景如程式清單 31和程式清單 32所示。

程式清單 31  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 %dn", 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;

}

程式清單 32  B進程程式碼

#include<stdio.h>

intmain (intargc, char **argv)

{

    intreadfd;

    intwritefd;

 

    sscanf (argv[1], "%d:%d", &readfd, &writefd);    /* 解析引數,獲得檔案描述符      */

    printf("hellow readfd %d  writefd %dn", readfd, writefd);

 

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

        perror("write");

        return -1;

    }

    return  (0);

}

SylixOS執行結果如所示,B進程沒有繼承A進程的檔案描述符導致報錯。

31  SylixOS執行結果

      遇到這種情況,可以通過使用posix_spawn來替換systemposix_spawn函數建立子進程並繼承父系的檔案描述符,所以可以通過posix_spawn替換system實現。如程式清單 33所示,只需修改A進程,B進程不用修改。

程式清單 33  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 %dn", 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;

}

執行結果如圖 32所示,執行正確。

32  修改後執行結果

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-06/144762.htm


IT145.com E-mail:sddin#qq.com