写在开头
近日新型冠状肺炎很严重,学校也开不了学了,在MOOC上学习操作系统原理时
看到MOOC上推荐完成的实验题,在这里记录一下。
本篇给出 4.1,4.2两题的解析,3-7在下一篇中分享
4.1 (实验目的:熟悉Window进程创建过程)在Windows环境下,利用高级语言编程环境(限定为VS环境或VC环境)调用相关的系统调用(CreateProccess,即系统API)实现一个包括“进程创建,文件读写”的应用程序。有一个文本文件CommandList.txt,第一行是说明性文字:本文件最后一次打开和运行日期是20190407。第二行开始每行是一个可执行程序的名称(含路径)。编写一个应用程序能打开该文件,并顺序执行其中的每个程序,并更新文件第一行中的日期。
[下面有一个文本文件CommandList.txt的截图]
| 本文件最后一次打开和运行日期是20190407 |
| c:\Windows\system32\notepad.exe |
| c:\Windows\system32\calc.exe |
| c:\Windows\system32\mspaint.exe |
|-------------------------------------------------------------------|
4.2 (实验目的:熟悉Linux fork创建进程的方法)在Ubuntu或Fedora环境使用fork函数创建一对父子进程,分别输出各自的进程号和提示信息串。
----------------------------------------------------------------------------------------------------
4.1Window进程创建
运行效果
三个进程被打开
且文件第一行的日期更改了
代码展示
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<time.h>
#define LINE 1024//一行最大字符数
char nowtime[64];//存储获取的当前时间
void getCurrentTime()
{
struct tm t; //tm结构指针
time_t now; //声明time_t类型变量
time(&now); //获取系统日期和时间
localtime_s(&t, &now); //获取当地日期和时间
strftime(nowtime, sizeof(nowtime), "%Y%m%d\0", &t); //年月日 ->nowtime
}
//该函数用于将文件第一行改变
void changeData(FILE* fp)
{
//采用:另创建一个备份文件,改变第一行,再把无关行复制过去,
//然后删除原文件,讲备份文件改名为原文件名
char tmpname[] = "tmp";//临时新文件名
FILE* fpNew;
//打开临时文件
errno_t err;
if ((err = fopen_s(&fpNew, tmpname, "w")) != 0)//w表示对文件可写
{
printf("文件打开失败!");
exit(1);
}
char buf[LINE]= "本文件最后一次打开和运行日期是";
getCurrentTime();//加载时间 将时间赋给nowtime[]
strcat_s(buf,nowtime);//将时间连接到后面
strcat_s(buf, "\n");//末尾加一个换行
char* p;
fputs(buf, fpNew);//将buf里的内容输入文件中
fgets(buf, LINE, fp);//这里读取第一行只是为了指针指向下一行
/*
解释一下,fgets()第一次运行会把第一行读出来,第二次运行会读出第二行
所以这里运行一次,是因为拷贝只从第二行开始
*/
//循环将原文件2-n行复制到临时文件
while (1)
{
p = fgets(buf, LINE, fp);
if (p == NULL)
break;//判断是否读取完
fputs(buf, fpNew);
}
fclose(fp);
fclose(fpNew);
remove("D:\\C语言相关\\我的代码\\操作系统原理\\创建进程\\CommandList.txt"); //删除原文件
rename(tmpname, "D:\\C语言相关\\我的代码\\操作系统原理\\创建进程\\CommandList.txt"); //重命名新文件
}
int main()
{
FILE* fp;
errno_t err;
if ((err = fopen_s(&fp, "D:\\C语言相关\\我的代码\\操作系统原理\\创建进程\\CommandList.txt", "r"))!=0)//r表示对文件可读
{
printf("文件打开失败!");
return 0;
}
//修改第一行: 本文件最后一次打开和运行日期是~~~~
changeData(fp);
//因为fgets而每次读取一行且不能回头,只能再打开一遍文件,使得fgets读取的是第一行
if ((err = fopen_s(&fp, "D:\\C语言相关\\我的代码\\操作系统原理\\创建进程\\CommandList.txt", "r")) != 0)//r表示对文件可读
{
printf("文件打开失败!");
return 0;
}
char buf[LINE];
char* p;
//读取一下第一行跳过他
p = fgets(buf, LINE, fp);
while (1)
{
p = fgets(buf, LINE, fp);
if (p == NULL)
break;
//这里讲一下,因为fgets,会把每句后面的换行符'\n'也读取,但是这样子是运行不了的,
//得把'\n'删掉,用'\0'做结尾
int length = strlen(buf);
if (buf[length - 1] == '\n')
buf[length - 1] = '\0';
//进程的参数
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
BOOL ret;
si.dwFlags = STARTF_USESHOWWINDOW;//指定wShowWindow成员有效
si.wShowWindow = TRUE;//是否显示创建出来的进程窗口
//将char 转为 TCHAR,因为(下面是一位大神讲的)
//lpCommandLine是LPTSTR而不是LPCTSTR,所以这个参数不能是字符串常量,
//必须是可写的字符串数组
//然后我看另一位大神的代码 发现他是用的 TCAHR 可行0.0嘿嘿
//(我在下面会给出两个大神的链接)
TCHAR command[LINE];
MultiByteToWideChar(CP_ACP, 0, buf, -1, command, LINE);
//创建一个进程,可以用它来执行一个程序
ret = CreateProcess(NULL, command, NULL, NULL, FALSE,
CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if (ret == false)
printf("进程创建失败");
}
return 0;
}
简单解释一下
先把两位大神的链接发一下:
各个参数的含义:Windows下创建进程-CreateProcess()
实例:VC++ 使用CreateProcess创建新进程
至于代码的话,我在上面又添加了很多注释,大家可以对照注释理解,如果有不明白,或者要指正的欢迎评论区留言。
4.2Linux fork创建进程
运行效果
输出了父进程和子进程的进程号
代码展示
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
void main()
{
//先输出该进程的进程号
fprintf(stdout,"I am the first process,my pid is %d,my parent pid is %d\n",getpid(),getppid());
//创建进程
pid_t pid;
if((pid=fork())<0)
{
//如果进程创建失败
fprintf(stderr,"fork failed!");
exit(0);
}
else if(pid==0)//子进程fork()返回值为0
fprintf(stdout,"I am the child process,my pid is %d,my parent pid is %d\n",getpid(),getppid());
else//父进程fork()返回值为子进程进程号
fprintf(stdout,"I am the parent process,my pid is %d,my child pid is %d,my parent pid is %d\n",getpid(),pid,getppid());
}
简单解释一下
每个进程都有一个进程id(大于0的整数),
getpid()可以返回进程id,getppid()返回父进程的pid。
fork() 会创建一个子进程,
在父进程中返回值为子进程的id,在子进程中返回值为0
参考资料:Linux环境下编程(一)——进程fork()的使用
写在结尾
希望以上可以帮到你!
如有错误,或不同想法,欢迎指出,互相学习共同进步!