深入了解Linux:正在运行的进程

1. 介绍

在深入了解Linux系统的运行原理之前,我们先来了解一下Linux中的进程。进程是指在操作系统中运行的一个程序,它是系统进行资源分配和调度的基本单位。每个进程都有自己的虚拟地址空间、代码段、数据段和堆栈等。

2. 查看正在运行的进程

Linux提供了多种方法来查看正在运行的进程,以便我们了解系统的运行情况。

2.1 top命令

top命令是一个基于字符界面的动态进程查看工具,通过该命令可以实时地查看系统中的进程情况。

top

在top输出的结果中,我们可以看到每个进程的PID(进程ID)、USER(进程所属用户)、PR(进程优先级)、NI(优先级调整值)、VIRT(虚拟内存使用量)、RES(物理内存使用量)等信息。

2.2 ps命令

ps命令是一个用于报告当前系统中的进程状态的命令。它可以显示出运行在系统中的进程列表。

ps -ef

ps命令的输出结果中包含有各个进程的PID、PPID(父进程ID)、USER(进程所属用户)、%CPU(CPU使用率)、%MEM(内存使用率)等信息。

3. 进程状态

在Linux系统中,每个进程都有自己的状态。根据进程的状态,我们可以了解到进程当前所处的位置和状态。

3.1 运行状态(R)

运行状态表示进程正在运行或者正在被调度执行。

int main()

{

while(1) {

// 一直执行

}

return 0;

}

在上述代码中,主进程会一直运行,直到用户手动终止。

3.2 睡眠状态(S)

睡眠状态表示进程正在等待某一事件的发生,比如等待用户输入、等待网络数据接收等。

int main()

{

char buf[1024];

fgets(buf, sizeof(buf), stdin);

return 0;

}

在上述代码中,主进程会等待用户输入一行字符串,直到用户按下回车键才会继续执行。

3.3 僵尸状态(Z)

僵尸状态表示进程已经结束执行,但是其父进程还没有对其进行善后处理。

int main()

{

pid_t pid = fork();

if (pid == 0) {

exit(0);

} else {

while(1) {

// 父进程不退出

}

}

return 0;

}

在上述代码中,子进程会立即退出,但是父进程会一直运行。子进程退出后,父进程并没有对其进行回收,导致子进程变成了僵尸进程。

4. 进程间通信

在Linux系统中,进程之间可以通过多种方式进行通信,以便实现数据交换和协作工作。

4.1 管道(Pipe)

管道是一种半双工的通信方式,可以将一个进程的输出连接到另一个进程的输入,实现它们之间的数据传递。

int main()

{

int fd[2];

char buf[1024];

pipe(fd);

if (fork() == 0) {

close(fd[0]);

write(fd[1], "Hello", 5);

exit(0);

} else {

close(fd[1]);

read(fd[0], buf, sizeof(buf));

printf("%s\n", buf);

}

return 0;

}

在上述代码中,通过pipe函数创建了一个管道,然后通过fork函数创建了一个子进程。子进程关闭了管道的读端,向管道中写入了一个字符串,然后退出。父进程关闭了管道的写端,从管道中读取数据,并打印出来。

4.2 共享内存(Shared Memory)

共享内存是指多个进程共享同一块物理内存区域,从而实现数据的共享。进程可以直接读写共享内存中的数据,避免了数据的拷贝开销。

int main()

{

int shmid;

char *shmaddr;

shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0666);

shmaddr = (char *)shmat(shmid, NULL, 0);

if (fork() == 0) {

strcpy(shmaddr, "Hello");

exit(0);

} else {

wait(NULL);

printf("%s\n", shmaddr);

shmdt(shmaddr);

shmctl(shmid, IPC_RMID, NULL);

}

return 0;

}

在上述代码中,首先通过shmget函数创建了一个共享内存区域,然后通过shmat函数将共享内存附加到当前进程的地址空间中。子进程向共享内存中写入了一个字符串,父进程等待子进程退出后,从共享内存中读取数据,并打印出来。

4.3 消息队列(Message Queue)

消息队列是一个链表,用于存放消息的缓冲区。进程可以通过消息队列向其他进程发送消息,以便进行通信。

int main()

{

int msgid;

struct msgbuf msg;

msgid = msgget(IPC_PRIVATE, IPC_CREAT | 0666);

if (fork() == 0) {

msg.mtype = 1;

strcpy(msg.mtext, "Hello");

msgsnd(msgid, &msg, sizeof(msg.mtext), 0);

exit(0);

} else {

wait(NULL);

msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0);

printf("%s\n", msg.mtext);

msgctl(msgid, IPC_RMID, NULL);

}

return 0;

}

在上述代码中,首先通过msgget函数创建了一个消息队列,然后通过msgsnd函数向消息队列中发送了一条消息。父进程等待子进程退出后,从消息队列中读取消息,并打印出来。

5. 总结

本文介绍了Linux系统中的进程及其相关内容。我们了解到如何查看正在运行的进程,进程的不同状态以及进程间的通信方式。了解这些内容对于我们深入理解Linux系统的运行原理和开发高效、稳定的应用程序都非常重要。

操作系统标签