《LINUX教程:SylixOS 的system使用》要点:
本文介绍了LINUX教程:SylixOS 的system使用,希望对您有用。如果有疑问,可以联系我们。
SylixOS是一款为大型嵌入式系统设计的硬实时系统,支持使用system调用执行命令.SylixOS为了保证实时性在system的实现上和Linux有所差别,本文着重介绍SylixOS如何实现system和在使用system时必要注意的事项.
SylixOS为保证系统的实时性所以没有实现fork功效,Linux下system是使用fork实现的.而SylixOS则通过使用内核的shell线程实现system功效.
Linux下system会调用fork发生子进程,由子进程execve调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程.
因为Linux下是通过fork实现system,所以被执行的命令继承父系的一些资源(比如文件描述符,父系的工作路径等).同时能够实现异步执行和同步执行,同步执行即父系等待system调用运行结束(包含system调用的命令执行结束);异步即不等待,父系继续运行.
2.2
SylixOS的system原理先容
#include<stdlib.h> intsystem(constchar *command); |
函数成功返回 0,失败返回-1,并设置差错码.
SylixOS的system是先创建一个内核的shell线程,然后通过内核的shell线程执行system必要执行的命令.
如果使用system调用执行一个进程,则同时启动一个内核线程来join等待清除该进程.如果使用system调用执行一个shell命令,则直接由内核线程t_tshell负责清除.如图 21所示,由open(pid=5)调用system执行hellow(pid=6),而内核创立一个hellow(pid=0)的内核线程join等待.
图 21 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的这个功能.
在移植Linux应用程序时,在某些特定的场景上Linux用户会在A进程通过system调用B进程,同时通过传参把一些文件描述符传递到B进程.因为Linux下B进程承继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 %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; } |
法式清单 32 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进程的文件描述符导致报错.
图 31 SylixOS运行成果
遇到这种情况,可以通过使用posix_spawn来替换system.posix_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 %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; } |
运行成果如图 32所示,运行正确.
图 32 修改后运行成果
本文永远更新链接地址:
学习更多LINUX教程,请查看站内专栏,如果有LINUX疑问,可以加QQ交流《LINUX教程:SylixOS 的system使用》。