Linux 命令-进程
linux进程相关命令。
ps
a:显示所有终端机下的进程,包括其他用户的进程。u:以用户为主的格式来显示进程状况。x:显示没有控制终端的进程。
free
该命令可以显示总的、已用的、可用的物理内存,以及交换空间的信息。
➜ ~ free -h
total used free shared buff/cache available
Mem: 1.9Gi 691Mi 436Mi 11Mi 785Mi 1.0Gi
Swap: 0 0 0top
该命令可以实时显示进程状态,类似于 Windows 的任务管理器。在 top 的界面中,可以看到内存的使用情况。
➜ ~ top
top - 16:58:01 up 26 days, 2:43, 1 user, load average: 0.01, 0.01, 0.00
Tasks: 95 total, 1 running, 94 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.2 sy, 0.0 ni, 99.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 1913.8 total, 436.0 free, 692.0 used, 785.8 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 1032.7 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
699 root 10 -10 141356 22920 0 S 1.0 1.2 212:57.52 AliYunDunMonito
551 root 20 0 689564 14572 9552 S 0.3 0.7 31:55.13 aliyun-service
611 root 20 0 2517508 266936 1292 S 0.3 13.6 208:06.56 nessusd
626 root 20 0 42184 964 0 S 0.3 0.0 23:46.46 AliYunDunUpdate
687 root 10 -10 88304 8836 6200 S 0.3 0.5 125:00.14 AliYunDun
15417 root 20 0 724344 5448 0 S 0.3 0.3 4:03.85 clash-linux-amd
1 root 20 0 169528 5552 3140 S 0.0 0.3 0:29.79 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreaddvmstat
➜ ~ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 446244 90108 714600 0 0 371 43 9 2 0 0 98 1 0通过进程名 查看进程打开文件的句柄
systemctl show --property MainPID --value nessusd | xargs -I {} lsof -p {}COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nessus-se 554 root cwd DIR 254,1 4096 2 /
nessus-se 554 root rtd DIR 254,1 4096 2 /
nessus-se 554 root txt REG 254,1 39456 1317347 /opt/nessus/sbin/nessus-service
nessus-se 554 root mem REG 254,1 1824496 787069 /usr/lib/x86_64-linux-gnu/libc-2.28.so
nessus-se 554 root mem REG 254,1 100712 786453 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
nessus-se 554 root mem REG 254,1 1579448 787072 /usr/lib/x86_64-linux-gnu/libm-2.28.so
nessus-se 554 root mem REG 254,1 1570256 789763 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
nessus-se 554 root mem REG 254,1 146968 787087 /usr/lib/x86_64-linux-gnu/libpthread-2.28.so
nessus-se 554 root mem REG 254,1 14592 787071 /usr/lib/x86_64-linux-gnu/libdl-2.28.so
nessus-se 554 root mem REG 254,1 19048 786461 /usr/lib/x86_64-linux-gnu/libanl-2.28.so
nessus-se 554 root mem REG 254,1 165632 786455 /usr/lib/x86_64-linux-gnu/ld-2.28.so
nessus-se 554 root 0r CHR 1,3 0t0 21 /dev/null
nessus-se 554 root 1u unix 0x0000000053591e84 0t0 14700 type=STREAM
nessus-se 554 root 2u unix 0x0000000053591e84 0t0 14700 type=STREAM通过进程名 查看其网络连接状态
➜ ~ lsof -i -P -n | grep nessusd
nessusd 611 root 19u IPv4 7391772 0t0 TCP *:8834 (LISTEN)
nessusd 611 root 20u IPv6 7391773 0t0 TCP *:8834 (LISTEN)查看本机进程和外部端口的数据包
tcpdump -i eth0 tcp port 8834 and host 222.70.235.17617:24:08.675102 IP 176.235.70.222.broad.xw.sh.dynamic.163data.com.cn.53238 > AliCloud-2C2G.8834: Flags [S], seq 484590853, win 65535, options [mss 1452,nop,wscale 6,nop,nop,TS val 3440648465 ecr 0,sackOK,eol], length 0
17:24:08.675160 IP AliCloud-2C2G.8834 > 176.235.70.222.broad.xw.sh.dynamic.163data.com.cn.53238: Flags [S.], seq 724970684, ack 484590854, win 28960, options [mss 1460,sackOK,TS val 3618397675 ecr 3440648465,nop,wscale 7], length 0
17:24:08.675695 IP 176.235.70.222.broad.xw.sh.dynamic.163data.com.cn.53239 > AliCloud-2C2G.8834: Flags [S], seq 287310922, win 65535, options [mss 1452,nop,wscale 6,nop,nop,TS val 4125725884 ecr 0,sackOK,eol], length 0
17:24:08.675705 IP AliCloud-2C2G.8834 > 176.235.70.222.broad.xw.sh.dynamic.163data.com.cn.53239: Flags [S.], seq 1956095185, ack 287310923, win 28960, options [mss 1460,sackOK,TS val 3618397676 ecr 4125725884,nop,wscale 7], length 0
17:24:08.687070 IP 176.235.70.222.broad.xw.sh.dynamic.163data.com.cn.53238 > AliCloud-2C2G.8834: Flags [.], ack 1, win 2070, options [nop,nop,TS val 3440648476 ecr 3618397675], length 0
17:24:08.687107 IP 176.235.70.222.broad.xw.sh.dynamic.163data.com.cn.53238 > AliCloud-2C2G.8834: Flags [P.], seq 1:1766, ack 1, win 2070, options [nop,nop,TS val 3440648476 ecr 3618397675], length 1765
17:24:08.687120 IP AliCloud-2C2G.8834 > 176.235.70.222.broad.xw.sh.dynamic.163data.com.cn.53238: Flags [.], ack 1766, win 254, options [nop,nop,TS val 3618397687 ecr 3440648476], length 0
17:24:08.687717 IP 176.235.70.222.broad.xw.sh.dynamic.163data.com.cn.53239 > AliCloud-2C2G.8834: Flags [.], ack 1, win 2070, options [nop,nop,TS val 4125725895 ecr 3618397676], length 0找到某个服务的运行目录和所涉命令
➜ ~ systemctl list-units --type=service --state=runningUNIT LOAD ACTIVE SUB DESCRIPTION
aegis.service loaded active running Aegis Service
aliyun.service loaded active running Aliyun Assist
AssistDaemon.service loaded active running AssistDaemon
chrony.service loaded active running chrony, an NTP client/server
containerd.service loaded active running containerd container runtime
cron.service loaded active running Regular background program processing daemon
dbus.service loaded active running D-Bus System Message Bus
docker.service loaded active running Docker Application Container Engine
getty@tty1.service loaded active running Getty on tty1
nessusd.service loaded active running The Nessus Vulnerability Scanner
postgresql@11-main.service loaded active running PostgreSQL Cluster 11-main
rsyslog.service loaded active running System Logging Service
serial-getty@ttyS0.service loaded active running Serial Getty on ttyS0
ssh.service loaded active running OpenBSD Secure Shell server
systemd-journald.service loaded active running Journal Service
systemd-logind.service loaded active running Login Service
systemd-networkd.service loaded active running Network Service
systemd-udevd.service loaded active running udev Kernel Device Manager
user@0.service loaded active running User Manager for UID 0CGroup
Control Group是内核的一部分,用于限制,记录和隔离进程组使用的物理资源。
➜ ~ systemctl status nessusd
● nessusd.service - The Nessus Vulnerability Scanner
Loaded: loaded (/lib/systemd/system/nessusd.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2024-03-30 14:14:37 CST; 3 weeks 5 days ago
Main PID: 554 (nessus-service)
Tasks: 16 (limit: 2261)
Memory: 838.2M
CGroup: /system.slice/nessusd.service
├─554 /opt/nessus/sbin/nessus-service -q
└─611 nessusd -q
Mar 30 14:14:37 AliCloud-2C2G systemd[1]: Started The Nessus Vulnerability Scanner.
Mar 30 14:15:09 AliCloud-2C2G nessus-service[554]: Cached 286 plugin libs in 186msec
Mar 30 14:15:09 AliCloud-2C2G nessus-service[554]: Cached 286 plugin libs in 81msec➜ ~ systemctl show --property MainPID nessusd.service --value
554sudo ls -l /proc/554/cwd➜ ~ sudo ls -l /proc/554/cwd
lrwxrwxrwx 1 root root 0 Apr 22 00:05 /proc/554/cwd -> /shell中一个线程读写文件 另一个线程可以删除这个文件吗
#!/bin/bash
# 创建一个名为testfile的文件
echo "Start" > testfile
# 启动一个子进程来循环写入文件
(
while true; do
echo "Writing to file..."
echo "Data" >> testfile
sleep 1
#cat testfile
done
) &
# 记住子进程的PID,以便稍后可以停止它
pid=$!
# 等待一会儿让写入进程有机会运行
sleep 5
# 删除文件
echo "Deleting file..."
rm testfile
echo "kill......"
sleep 2
# 停止写入进程
kill $pid
# 检查文件是否存在
if [[ -e testfile ]]; then
echo "File exists"
else
echo "File does not exist"
fi进程和线程都是操作系统进行资源分配和调度的基本单位,但是它们之间有一些关键的区别:
- 独立性:进程是系统资源分配的最小单位,线程是系统调度的最小单位。进程拥有独立的地址空间,每启动一个进程,系统就会为它分配独立的地址空间,建立数据表来维护代码段、堆栈段和数据段等信息。线程是进程的一部分,是比进程更小的能独立运行的基本单位,它复用父进程的地址空间,并共享其资源。
- 开销:由于进程具有独立的地址空间,因此进程之间的切换需要较大的开销。相比之下,线程可以看作轻量级的进程,同一进程内的线程切换开销小,因为它们可以共享相同的上下文。
- 通信方式:进程间通信(IPC)需要操作系统提供机制来进行,常见的进程间通信方式有管道、消息队列、信号量、共享内存等。而线程间可以直接通信,线程共享相同的地址空间,所以一个线程可以访问同一进程下的其他线程的数据,线程间通信更方便,开销更小。
- 改变环境:每个进程都有自己的独立环境,改变进程的执行环境(如改变工作目录、用户ID、打开文件等)不会影响其他进程。而线程共享进程的执行环境,一个线程改变了执行环境,其他线程也会受到影响。
- 生命周期:进程有自己的生命周期,从创建到终止。线程的生命周期则存在于进程的生命周期之内,线程的创建和终止都需要在其父进程的生命周期内完成。
综上,我们可以看出,子进程和线程既有相似之处,也有区别。它们都可以用于并发执行代码,但是由于它们的特性不同,所以在实际使用中,选择使用子进程还是线程,需要根据具体的需求和场景来决定。
子进程和父进程是操作系统中进程间的一种重要关系。在多任务操作系统中,进程是资源分配和调度的基本单位。当一个进程创建了一个新的进程,创建的进程被称为子进程,而原进程被称为父进程。
以下是父进程和子进程之间的一些关系:
- 创建关系:父进程是通过调用某种形式的创建进程的系统调用(例如 Unix 系统中的
fork()函数)来创建子进程的。创建出来的子进程是父进程的副本,它继承了父进程的许多属性,如环境变量、打开的文件描述符等。 - 资源共享:子进程会继承父进程的环境设置和部分资源,但是子进程有自己的数据空间,子进程对数据的修改不会影响父进程。
- 生命周期:父进程和子进程的生命周期可以是独立的。父进程在创建子进程后可以继续执行其他任务,也可以等待子进程结束。同样,即使父进程结束,子进程也可以继续运行,这时的子进程通常被称为孤儿进程。
- 进程间通信:父进程和子进程可以通过各种进程间通信(IPC)机制进行通信,如管道、消息队列、共享内存等。
- 进程ID:每个进程都有一个唯一的进程ID。子进程有自己的新进程ID,同时还知道父进程的ID。父进程可以通过子进程的ID来控制或者接收子进程的状态信息。 父子进程机制是多任务系统实现并发处理的一种重要方式,通过进程的分裂,可以使得多个任务并行处理,提高系统的效率。
Writing to file...
Writing to file...
Writing to file...
Writing to file...
Writing to file...
Deleting file...
File does not exist
[1] + 25485 terminated ( while true; do; echo "Writing to file..."; echo "Data" >> testfile; sleep 1)C++处理linux信号
在Linux中,有许多不同的信号可以发送给进程。以下是一些常见的信号:
SIGINT:当用户按下Ctrl+C时发送的中断信号。SIGQUIT:当用户按下Ctrl+\时发送的退出信号。SIGTERM:系统默认的终止信号,可以被进程捕获并决定如何处理。SIGKILL:立即终止进程的信号,进程无法捕获或忽略此信号。SIGHUP:通常用于指示控制终端已断开连接,但也常被用于其他目的,例如告诉守护进程重新读取其配置文件。SIGSEGV:当进程执行了一个无效的内存引用时发送的信号,通常导致进程终止并转储核心。
#include <csignal>
#include <iostream>
void handle_sigint(int sig) {
std::cout << "Caught signal " << sig << std::endl;
// 在此处执行你希望在接收到SIGINT时执行的操作...
}
int main() {
std::signal(SIGINT, handle_sigint);
while (true) {
// 你的程序主循环...
}
return 0;
}在C++中,你可以使用signal函数来注册一个信号处理函数,这个函数将在接收到指定的信号时被调用。
在上面的例子中,我们定义了一个名为handle_sigint的函数,然后使用std::signal(SIGINT, handle_sigint);来注册它作为SIGINT信号的处理函数。这意味着,每当进程接收到SIGINT信号时,handle_sigint函数就会被调用。
请注意,不是所有的信号都可以被捕获。例如,SIGKILL和SIGSTOP信号不能被捕获,它们总是会立即终止进程或停止进程。
➜ General git:(master) ✗ ps -a | grep test
96928 ttys006 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox test
96146 ttys009 2:14.54 /Users/zq/WorkSpace/test强制退出
➜ General git:(master) ✗ kill -SIGTERM 96146➜ WorkSpace cd "/Users/zq/WorkSpace/" && g++ -std=c++17 test.cpp -o test && "/Users/zq/WorkSpace/"test
[1] 96146 terminated "/Users/zq/WorkSpace/"test退出信号
➜ General git:(master) ✗ kill -SIGINT 99123➜ WorkSpace cd "/Users/zq/WorkSpace/" && g++ -std=c++17 test.cpp -o test && "/Users/zq/WorkSpace/"test
Caught signal 2程序继续运行。
通过端口号查看进程状态
➜ ~ lsof -i :8834
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nessusd 611 root 19u IPv4 7391772 0t0 TCP *:8834 (LISTEN)
nessusd 611 root 20u IPv6 7391773 0t0 TCP *:8834 (LISTEN)互斥和同步
互斥(Mutual Exclusion)和同步(Synchronization)是操作系统和并发编程中的重要概念。
互斥:互斥是一种机制,用于防止两个或多个进程(或线程)同时进入临界区域(即一次只能由一个进程访问的代码区域)并可能导致数据不一致的情况。这主要用于保护共享资源,如文件、内存或硬件设备,防止同时被多个进程修改。
同步:同步是一种机制,用于协调两个或多个进程(或线程)的执行顺序。这通常用于确保某些操作在其他操作之前或之后完成,或者用于等待某个条件成立(例如,等待另一个进程完成其工作)。
以下是Linux中实现互斥和同步的一些机制:
互斥锁(Mutex):互斥锁是一种最常用的互斥机制。一个进程在进入临界区之前需要获取互斥锁,如果锁已经被另一个进程持有,则该进程将阻塞(等待)。当持有锁的进程离开临界区时,它将释放锁,这样其他等待的进程就可以获取锁并进入临界区。
信号量(Semaphore):信号量可以被用来实现互斥和同步。一个信号量有一个与之关联的计数器,如果计数器大于0,那么获取信号量的进程可以继续执行;如果计数器等于0,那么获取信号量的进程将阻塞。信号量的计数器可以被任何持有该信号量的进程增加或减少。
条件变量(Condition Variable):条件变量常用于实现同步。一个进程可以等待一个条件变量,这将导致该进程阻塞,直到另一个进程触发该条件变量。这通常用于实现“等待某个条件成立”这样的同步。
管道(Pipe)和消息队列(Message Queue):管道和消息队列允许进程之间发送和接收数据,这也可以实现同步。例如,一个进程可以等待另一个进程通过管道发送的数据。
以上这些都是进程级别的互斥和同步机制。在线程级别,互斥和同步可以通过类似的机制实现,例如互斥锁、条件变量和barrier等。这些通常由线程库(如POSIX Threads或C++11中的std::thread)提供。
#include <stdio.h>
#include <pthread.h>
// 互斥锁和条件变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// 产品数量
int products = 0;
// 生产者线程函数
void* producer(void* arg) {
while (1) {
pthread_mutex_lock(&mutex);
products++;
printf("Produced one product, total number of products: %d
", products);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
// 消费者线程函数
void* consumer(void* arg) {
while (1) {
pthread_mutex_lock(&mutex);
while (products == 0) {
pthread_cond_wait(&cond, &mutex);
}
products--;
printf("Consumed one product, total number of products: %d
", products);
pthread_mutex_unlock(&mutex);
}
}
int main() {
pthread_t prod, cons;
// 创建生产者和消费者线程
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
// 等待线程结束
pthread_join(prod, NULL);
pthread_join(cons, NULL);
return 0;
}在这个例子中,我们有一个生产者线程和一个消费者线程。生产者线程生产产品,消费者线程消费产品。
当生产者生产一个产品时,它会锁定互斥锁,增加产品数量,然后解锁互斥锁,并发送一个条件变量信号来唤醒可能正在等待产品的消费者线程。
消费者线程会尝试锁定互斥锁,然后检查产品数量。如果产品数量为0,它会等待条件变量。当生产者线程发送条件变量信号时,消费者线程会被唤醒,然后消费一个产品,解锁互斥锁。
优雅停止
优雅的停止机制通常意味着当你想要停止程序时,程序能够完成当前的工作,清理使用的资源,然后安全地退出,而不是立即停止并可能导致数据丢失或者资源泄漏。
一般通过 handle_signal() 处理SIGINT信号实现。