📅  最后修改于: 2023-12-03 14:48:13.658000             🧑  作者: Mango
在 Unix/Linux 操作系统中,进程控制是一个非常重要的任务。进程控制命令允许程序员管理和操作正在运行的进程,包括查看进程列表、启动新进程、停止或终止进程等。本文将介绍一些常用的进程控制命令。
ps
命令用于列出当前系统中运行的进程。以下命令将显示进程的 PID(进程标识符)、PPID(父进程标识符)、CPU 占用、内存占用以及进程状态等信息。
ps aux
top
命令以实时交互方式显示系统的进程状况。它可以按照 CPU 使用率或内存占用等指标进行排序,并可以动态更新显示结果。
top
fork()
系统调用用于创建一个新进程,该新进程是原始进程的副本。新进程将继承原始进程的代码、数据和文件描述符等属性。以下是一个使用 fork()
创建子进程的示例:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
pid_t pid;
pid = fork();
if (pid == 0) {
// 子进程
printf("Child process\n");
} else if (pid > 0) {
// 父进程
printf("Parent process\n");
} else {
// 创建进程失败
fprintf(stderr, "Fork failed\n");
return 1;
}
return 0;
}
exec
系列函数用于在当前进程中执行新的程序。它会用指定的可执行文件替换当前进程的代码段、数据段和堆栈等属性。以下是 execvp()
函数的一个示例:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char *binaryPath = "/bin/ls";
char *args[] = {"ls", "-l", NULL};
execvp(binaryPath, args);
// execvp() 函数只在执行失败时才返回,所以如果执行到这里表示出错了
fprintf(stderr, "Execution failed\n");
return 1;
}
kill
命令用于向指定的进程发送信号。一个常用的信号是 SIGKILL,用于强制终止进程。以下命令将向进程号为 PID
的进程发送 SIGKILL 信号:
kill -9 PID
pkill
命令用于根据进程名或其他属性向进程发送信号。以下命令将向名为 process_name
的进程发送 SIGKILL 信号:
pkill -9 process_name
ps
命令还可以用于查看进程的状态信息。以下命令使用 ps
查看所有进程的运行状态:
ps -ef
renice
命令用于修改进程的优先级。以下命令将进程号为 PID
的进程的优先级调整为 NICE
:
renice NICE PID
nice
命令可以在运行新程序时为其指定优先级。以下命令将运行 command
并将其优先级设置为 NICE
:
nice -n NICE command
pipe
系统调用用于创建一个管道,可用于父子进程或者兄弟进程之间进行通信。以下是一个用于父子进程通信的例子:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 25
int main() {
int pipefd[2];
pid_t pid;
char message[BUFFER_SIZE] = "Hello, pipe!";
if (pipe(pipefd) == -1) {
fprintf(stderr, "Pipe failed\n");
return 1;
}
pid = fork();
if (pid == 0) {
// 子进程
close(pipefd[1]); // 关闭写端
// 从管道中读取消息
read(pipefd[0], message, BUFFER_SIZE);
printf("Child received: %s\n", message);
close(pipefd[0]);
} else if (pid > 0) {
// 父进程
close(pipefd[0]); // 关闭读端
// 向管道中写入消息
write(pipefd[1], message, strlen(message) + 1);
close(pipefd[1]);
} else {
// 创建进程失败
fprintf(stderr, "Fork failed\n");
return 1;
}
return 0;
}
socket
系统调用用于创建一个网络套接字,可用于不同计算机上的进程之间进行通信。通过套接字,进程可以进行双向的数据传输。以下是一个简单的使用套接字进行通信的例子:
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAX_BUFFER_SIZE 1024
#define PORT 8080
int main() {
int serverSocket, newSocket;
struct sockaddr_in serverAddress, clientAddress;
int addressLength = sizeof(serverAddress);
char buffer[MAX_BUFFER_SIZE] = {0};
if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = INADDR_ANY;
serverAddress.sin_port = htons(PORT);
if (bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}
if (listen(serverSocket, 3) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}
if ((newSocket = accept(serverSocket, (struct sockaddr *)&serverAddress, (socklen_t*)&addressLength)) < 0) {
perror("Accept failed");
exit(EXIT_FAILURE);
}
read(newSocket, buffer, MAX_BUFFER_SIZE);
printf("Received message: %s\n", buffer);
close(newSocket);
close(serverSocket);
return 0;
}
本文介绍了在 Unix/Linux 中的一些常用进程控制命令,包括进程列表和状态、进程创建和管理、进程状态和控制以及进程通信等方面的内容。熟练使用这些命令能够提高程序员在 Unix/Linux 环境下的工作效率。请记得根据实际需求和情况选择适当的命令进行使用。