csdn推荐
目录
1 理解线程与进程 1.1 线程与进程
进程:进程是操作系统进行资源分配和调度的一个独立单位,每个进程都有自己的独立内存空间,至少有一个线程,即主线程。进程可以理解为完成一件事的完整解决方案,而线程可以理解为这个解决方案中的的一个步骤,可能这个解决方案就这只有一个步骤,也可能这个解决方案有多个步骤。
线程:线程是进程中的一个执行流,是CPU调度和分派的基本单位,它被包含在进程之中,进程包含一个或者多个线程。
1.2 并发与并行
并发:是指两个或多个事件在同一时间间隔发生,并发是针对单核 CPU 提出的,在同一CPU上的多个事件。
并行:是指两个或者多个事件在同一时刻发生,并行则是针对多核 CPU 提出,在不同CPU上的多个事件
2 进程与程序 2.1 程序如何开始?
在Linux系统中,程序的main()函数是由操作系统的程序加载器调用的。当用户通过命令行或其他方式启动一个C程序时,操作系统会加载程序的可执行文件到内存中,并初始化程序的执行环境,包括设置堆栈、分配内存等。随后,加载器会定位到程序的入口点,也就是main()函数,并将其传递给CPU开始执行。
main()函数的调用过程与进程的生命周期紧密相关。在Linux中,每个运行的程序都是一个或多个进程,当main()函数开始执行时,它实际上是在进程的上下文中运行的,进程是操作系统分配资源和调度任务的基本单位。
2.2 程序如何结束?
程序结束其实就是进程终止,进程终止的方式通常有多种,大体上分为正常终止和异常终止, 正常终止包括:
atexit()库函数用于注册一个进程在正常终止时要调用的函数,其函数原型如下所示:
#include
int atexit(void (*function)(void));
下面的程序是atexit()库函数的调用实例:
#include
#include
// 注册的退出函数,将在程序退出时调用
static void bye(void)
{
puts("Goodbye!");
}
int main(int argc, char *argv[])
{
// 使用atexit注册退出时调用的函数
// 如果注册失败,将打印错误信息并以非零状态退出
if (atexit(bye) != 0) {
fprintf(stderr, "cannot set exit functionn");
exit(-1);
}
exit(0);
}
atexit函数被用来注册bye函数,这样当程序退出时,bye函数会被自动调用。如果atexit调用失败,程序将打印错误信息并通过exit(-1)状态退出。如果atexit调用成功,程序将正常执行,最后以通过exit(0)状态退出,此时bye函数会被自动调用。
3 进程号
进程号(PID)是操作系统分配给每个运行中的程序的唯一标识符,它允许系统和用户识别和管理不同的进程,确保每个进程都能独立地运行并访问系统资源。
在 Ubuntu 系统下执行 ps 命令可以查到系统中进程相关的一些信息,包括每个进程的进程号,如下所示:
上图中红框标识显示的是每个进程所对应的进程号,在某些系统调用中,进程号可以作为传入参数、有时也可作为返回值。譬如系统调用 kill()允许调用者通过进程号向某一个进程发送一个信号。
在应用程序中,可通过系统调用 getpid()来获取本进程的进程号,其函数原型如下所示:
#include
#include
pid_t getpid(void);
使用 getpid()函数获取进程的进程号:
#include // 包含标准输入输出库
#include
#include
// 定义main函数,程序的入口点
int main()
{
// 使用getpid()获取当前进程的进程号
pid_t pid = getpid();
// 打印进程号
printf("The process ID is: %dn", pid);
// 程序正常退出
return 0;
}
使用getpid()函数获取当前进程的进程号,并将其存储在pid_t类型的变量pid中。pid_t是一个通常用于存储进程ID的类型,它的定义依赖于具体的系统和编译器。
文章来源:https://blog.csdn.net/qq_41921826/article/details/140193190
微信扫描下方的二维码阅读本文
暂无评论内容