标签:ada you 中间 kernel hand lis not list note
功能:创建一个具有制定标识(ID)的进程
参数:进程标识、优先级、进程起始地址、CPU初始状态、资源清单等。
创建进程的过程
进程创建的伪代码
// CPU的状态,内存,优先级
Create(Si, Mi, Pi) {
// 分配新的PCB
p = Get_New_PCB();
// 分配进程的PID
pid = Get_New_PID();
// 设置进程的PID
p->ID = pid;
// CPU的状态
p->CPU_State = Si;
// 内存
p->Memory = Mi;
// 优先级
p->Priority = Pi;
// 进程状态
p->Status.Type = "Ready";
// 进程队列RL:Ready List
p->Status.List = RL;
...;
// 将进程p插入到就绪队列
Insert(RL, p);
// 调度程序
Scheduler();
}
功能
进程撤销的时机/事件
进程撤销的实现
功能:停止进程的执行,变为阻塞
阻塞的时机/事件
参数
进程阻塞的实现
功能:唤醒处于阻塞队列的某一个进程
引起唤醒的时机/事件
参数:被唤醒进程的标识
原语是由若干指令构成具有特定功能的函数
具有原子性,其操作不可分割
进程创建的原语:(同上伪代码),所以进程创建是一个原语
进程控制原语
#include <iostream>
#include <Windows.h>
using namespace std;
const char* NOTEPAD_PATH = "C:/Windows/System32/notepad.exe";
int main() {
system(NOTEPAD_PATH);
WinExec(NOTEPAD_PATH, SW_SHOWNORMAL);
ShellExecute(NULL, (LPCWSTR)L"open", (LPCWSTR)L"notepad.exe", NULL, NULL, SW_SHOWMAXIMIZED);
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL ret = CreateProcess(NULL, (LPWSTR)L"notepad.exe", NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi);
return 0;
}
以下三个函数都是对CreateProcess的封装
_DCRTIMP int __cdecl system(
_In_opt_z_ char const* _Command
);
WinExec(
_In_ LPCSTR lpCmdLine,
_In_ UINT uCmdShow
);
SHSTDAPI_(HINSTANCE) ShellExecuteW(_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters,
_In_opt_ LPCWSTR lpDirectory, _In_ INT nShowCmd);
CreateProcessW(
_In_opt_ LPCWSTR lpApplicationName, // 可执行程序名
_Inout_opt_ LPWSTR lpCommandLine, // [可执行程序名]程序参数
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags, // 创建标志(优先级……)
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCWSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOW lpStartupInfo, // 启动信息(进程启动的状态,是否显示窗口……)
_Out_ LPPROCESS_INFORMATION lpProcessInformation //
);
创建新进程
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
::CreateProcess((LPWSTR)L"C:/Windows/System32/notepad.exe", (LPWSTR)L"C:/readme.txt", NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi);
结束进程
WINBASEAPI DECLSPEC _NORETURN VOID WINAPI ExitProcess(UINT uExitCode);
WINBASEAPI WINBOOL WINAPI TerminateProcess(HANDLE hProcess, UINT uExitCode);
pid_t fork(void);
例子:
pid_t pid = fork();
#include <unistd.h>
#include <cstdio>
int main() {
pid_t pid;
int count = 0;
pid = fork();
printf("This is first time, pid = %d\n", pid);
printf("This is second time, pid = %d\n", pid);
count++;
printf("count = %d\n", count);
if (pid > 0) {
printf("This is the parent process,the child has the pid:%d\n", pid);
} else if (!pid) {
printf("This is the child Process.\n");
} else {
printf("fork failed.\n");
}
printf("This is third time, pid = %d\n", pid);
printf("This is fouth time, pid = %d\n", pid);
return 0;
}
运行结果
This is first time, pid = 1174
This is second time, pid = 1174
count = 1
This is the parent process,the child has the pid:1174
This is third time, pid = 1174
This is fouth time, pid = 1174
This is first time, pid = 0
This is second time, pid = 0
count = 1
This is the child Process.
This is third time, pid = 0
This is fouth time, pid = 0
Process finished with exit code 0
int main() {
fork(); // 子进程是父进程的复制,父子进程都输出了
printf("Hello World!\n");
return 0;
}
输出结果:
父子进程在并发运行
#include <unistd.h>
#include <cstdio>
int main() {
pid_t pid;
pid = fork();
if (pid == 0) {
printf("Hello World!\n");
} else if (pid > 0) {
printf("How are you!\n");
}
return 0;
}
输出结果:
父子进程谁先输出不确定
fork返回值pid**
Upon successful completion, fork() returns a value of 0 to the child process and returns the process ID of the child process to the parent process. Otherwise, a value of -1 is returned to the parent process, no child process is created, and the global variable errno is set to indicate the error.
修改:增加输出pid,运行结果如下
PID of current Process is : 1609
How are you! // 父进程
PID of current Process is : 0
Hello World! // 子进程
Process finished with exit code 0
在文件/kernel/fork.c中
int do_fork(unsigned long clone_flags,
unsigned long stack_start,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr) {
struct task_struct *p;
// 分配无力页面存放task_struct结构和内核空间的堆栈
p = alloc_task_struct();
// 把当前进程的task_struct结构中所有内容拷贝到新进程中
*p = *current;
// 判断用户进程数量是否超过了最大限制,否则不许fork
if ((&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur) {
goto bad_fork_free;
}
// 子进程状态设TASK_UNINTERRUPTIBLE
p->state = TASK_UNINTERRUPTIBLE;
// 拷贝进程的所有信息
copy_files(clone_flags, p);
copy_fs(clone_flags, p);
copy_mm(clone_flags, p);
// 进程创建后与父进程链接起来形成一个进程组
list_add(&p->thread_group, ¤t->thread_group);
// 唤醒进程,将其挂入可执行队列等待被调度
wake_up_process(p);s
}
exec函数簇(包括若干函数)
// unistd.h
int execl(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
int execle(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
int execlp(const char * __file, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
int execv(const char * __path, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
int execve(const char * __file, char * const * __argv, char * const * __envp) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
int execvp(const char * __file, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
标签:ada you 中间 kernel hand lis not list note
原文地址:https://www.cnblogs.com/iamfatotaku/p/12516468.html