首页 理论教育 进程线程的继承与执行结果获取方法探究

进程线程的继承与执行结果获取方法探究

时间:2026-01-27 理论教育 筱悦 版权反馈
【摘要】:函数中确定了句柄是否要继承给子进程,同时定义了进程可使用的环境变量。最后调用函数waitpid,父进程就可以获得子进程的exec是否成功的信息。在Linux中,执行函数exit可以退出当前进程,执行函数kill可以中止进程。

4.1.3.1 进程控制

(1)创建进程

在Windows中,函数CreateProcess用于创建一个指定名称和路径的新进程。函数中确定了句柄是否要继承给子进程,同时定义了进程可使用的环境变量。

在Linux中,首先通过函数fork 创建一个具有新的PID的子进程,然后使用setpgid 函数切换到新的PID,最后使用exec函数将现有进程改变为将要执行的进程。但是Linux的exec函数族成功执行后是不会有返回值的,因此执行ptrace函数来让子进程被父进程跟踪,若函数exec执行失败,则子进程向自己发一个SIGKILL信号。若函数exec执行成功,那么子进程会向自己发送一个SIGTRAP信号。最后调用函数waitpid,父进程就可以获得子进程的exec是否成功的信息。

(2)进程命令行

函数GetCommandLine用于获取进程命令行。

在Linux中,查找环境变量_COMMANDLINE,若有,将其内容输出,否则,通过读取ps-ef中的CMD栏来获得进程命令行。

(3)获得当前进程

函数GetCurrentProcess用来获得当前进程,返回的是伪句柄,值为-1。

在Linux中,可直接返回-1。

(4)获取进程号

函数GetProcessId 用于获得给定进程的进程号,函数GetCurrentProcessId 则用于获得当前进程的进程号。

在Linux中,要获得指定进程的进程号,首先判断进程句柄,若是伪句柄(-1),则表明指定进程就是当前进程,调用getpid 函数便可获得进程号,否则,读取进程句柄中存储的进程号。

(5)获取/设置进程的优先级

在Windows中,使用函数SetPriorityClass来设置特定进程的优先级等级,使用函数GetPriorityClass来获得特定进程的优先级等级。

在Linux中,可以使用函数setpriority来设置或者修改普通进程的优先级层次,还可以使用函数sched_setscheduler() 来修改正在运行的进程的调度优先级,也可以通过函数sched_setparam来仅修改进程优先级。相反,可以使用getpriority函数来获取进程的优先级层次。

(6)获取/设置环境变量

函数GetEnvironmentStrings用于获取所有环境变量字符串;函数GetEnvironmentVariable用来获得指定名称的环境变量,并存入缓冲之中;函数SetEnvironmentVariable则是用来为将给定值设置给指定名称的环境变量,若给定值为NULL,则意味着要删除该环境变量。

Linux中的environ 函数可以将Linux的环境变量数组转换为Windows的环境变量字符串。函数getenv可以实现函数GetEnvironmentVariable同样的功能。环境变量设置时,首先要进行判断,若给定值不为NULL,则调用函数setenv;若给定值为NULL,则需要调用函数unsetenv。

(7)进程退出/中止

函数ExitProcess用于退出当前进程,并将退出码设置为指定的值;函数TerminateProcess用于中止指定的进程,同时也将退出码设置为指定的值。

在Linux中,执行函数exit可以退出当前进程,执行函数kill可以中止进程。最后将退出码写入与进程建立关联的文件中,该文件中还记录了进程相关的其他信息。

4.1.3.2 线程控制

(1)线程创建(https://www.xing528.com)

在Windows中,函数CreateThread 用于创建一个线程并且返回一个完全访问权限的句柄。

函数的参数中,lpThreadAttributes是指向线程属性的指针,它决定了线程句柄是否能由子进程继承;参数dwStackSize是将要分配给新线程的以字节为单位的栈大小,栈大小应该是4 Kb 的非零整数倍,最小为8 Kb;lpStartAddress参数给出的是刚创建的线程要执行的函数的地址;lpParameter则指定了要传递给刚创建的线程的参数。

在Linux中,使用pthread 库调用函数pthread_create来派生线程,函数CreateThread 中的lpStartAddress和lpParameter参数相当于函数pthread_create中的参数start_address和arg,函数CreateThread 中的dwStackSize参数在线程属性对象中设置,但是在为新线程设置任何属性之前,都需要通过调用函数pthread_attr_init来初始化这个属性对象,之后调用函数pthread_attr_setstacksize来设置栈大小,最后还要调用函数pthread_attr_destroy来销毁属性对象。

(2)线程的挂起/恢复

函数SuspendThread 用于将指定线程挂起,并将挂起计数加1;而函数ResumeThread 则用于恢复执行指定的进程,挂起计数减1。

在Linux中,可以通过依次调用函数pthread_mutex_lock、pthread_mutex_unlock、pthread_cond_wait、pthread_cond_signal来实现线程的挂起与唤醒。

线程挂起的实现中,首先调用函数pthread_mutex_lock 为mut互斥量加锁,当执行到函数pthread_cond_wait时,此时如果满足条件,则将cond 条件变量加锁,再调用函数pthread_mutex_unlock 将mut互斥量解锁,此时线程挂起(不占用任何CPU周期)。

线程恢复的过程是,再次调用函数pthread_mutex_lock 为mut互斥量加锁,通过IF条件语句进行条件判断,如果满足条件,则函数pthread_cond_signal会唤醒挂起的线程,并通过调用函数pthread_mutex_unlock 释放互斥量mut。然后挂起的线程开始从pthread_cond_wait()执行,首先还要调用函数pthread_mutex_lock再次为mut加锁,再进行条件的判断,如果满足条件,则线程被唤醒进行处理,最后调用函数pthread_mutex_unlock 释放互斥量mut。

(3)线程退出/中止

函数ExitThread 用于退出当前线程,并将退出码设置为指定的值;函数TerminateThread 用于中止指定线程,并将退出码设置为指定的值;函数GetExitCodeThread 则用于获取指定线程的退出码。

在Linux中,调用pthread_exit函数便可以退出/中止当前线程,函数的参数是线程的退出码,通过函数pthread_join 就可以获得线程的退出码。

(4)线程切换

在Windows中,通过函数SwitchToThread 便可以从调度层面暂停当前线程的执行,切换至其他线程继续执行。在Linux中,对应的函数是sched_yield。

(5)线程号获取

函数GetThreadId 可以返回指定线程的线程号;函数GetCurrentThread 用来返回当前线程的句柄;函数GetCurrentThreadId 则可以获取当前线程的线程号。

在Linux中,要获得指定线程的线程号,首先判断线程句柄,若是伪句柄(-2),则表明指定线程就是当前线程,调用getpid 函数便可获得线程号,否则,读取线程句柄中存储的线程号。而要获得当前线程的句柄,直接返回伪句柄(-2)即可。

(6)获取/设置线程的优先级

在Windows中,使用函数SetThreadPriority来设置特定线程的优先级等级,使用函数GetThreadPriority来获得特定进程的优先级等级。

在Linux中,同样可以使用函数setpriority来设置或者修改普通线程的优先级层次,还可以使用函数pthread_setschedparam() 来修改正在运行的线程的调度优先级。相反,同样可以使用getpriority函数来获取线程的优先级层次。

(7)线程休眠

函数Sleep 用于让当前线程休眠指定时长,若时长设为INFINITE,则线程永久休眠。在Linux中,可以采用pthread_cond_timedwait函数来实现同样功能,函数中设置有等待条件变量cond,如果一直没有等待到条件变量cond,当超时,就返回,如果等待到条件变量cond,也返回。

(8)管道创建

函数CreatePipe用来创建一个指定读端(句柄)和写端(句柄)的无名管道。在Linux中,可以使用函数pipe实现同样功能,pipe参数中的两个文件描述符分别对应函数CreatePipe中的读端(句柄)和写端(句柄)。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈