PID为0的系统空闲进程连接状态为TIME_WAIT

本文解析了在网络连接中出现PID为0的SystemIdleProcess占用大量端口的原因,阐述了Time_Wait状态的作用及端口释放机制,并解释了为何这并不意味着系统受到病毒感染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果您使用命令提示符执行命令查看网络连接情况,您会发现,PID为0的System Idle Process(系统空闲进程)将会出现很多网络端口占用情况。下面是一个示例:
Proto  Local Address          Foreign Address        State           PID
TCP    127.0.0.1:30606        127.0.0.1:3129         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3131         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3133         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3135         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3137         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3139         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3141         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3143         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3145         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3147         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3149         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3151         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3153         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3155         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3157         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3159         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3161         TIME_WAIT       0
TCP    127.0.0.1:30606        127.0.0.1:3165         TIME_WAIT       0
我们这里使用了“netstat -a -n -o”命令,参数-a用来显示所有的连接和监听端口,参数-o用来显示相应系统进程的PID,使用了参数-n以数字(IP)的方式显示地址和端口。
    那么是不是说明计算机中了病毒了呢?其实并不是这样,这要从为什么系统空闲进程要占用端口说起了。
    通过仔细观察,我们可以发现,命令结果列出的所有PID为0的通信的状态均为Time_Wait,而决不会是Established建立状态或者是Listening监听状态,这个就要涉及到一个TCP Socket的问题了,有兴趣深入研究的朋友们可以查阅一下更多的有关文章,因为概念性的东西太多了,因此我们在此仅进行一个简要的解释。
    原因是这样的:
    一、关于Time_Wait状态:
          TCP TIME-WAIT 延迟断开TCP 连接时,套接字对被置于一种称为TIME-WAIT 的状态。这样,新的连接不会使用相同的协议、源 IP 地址、目标 IP 地址、源端口和目标端口,直到经过足够长的时间后,确保任何可能被错误路由或延迟的段没有被异常传送。因此,Time_Wait不是多余的状态,而是为了保证通信的正确性、准确性而存在的。而且,这样的状态往往都交给系统空闲进程处理了,因为具体的应用程序已经完成了通信过程,发出了数据。因此,这里PID为0的通信均是已“断开”的曾经被进程使用过的连接,而且还没有释放端口。
    二、关于端口的释放:
          什么时候释放,怎样释放呢?我们将这种套接字对不被其它连接重新使用的时间长度指定为两个MSL(最大段生存时间),即4 分钟。对于Windows NT 系统来说,这是默认设置。然而,在此默认设置下,某些网络应用程序在很短时间内执行多个出站连接,也就可能会在端口收回前用完所有的可用端口。
    三、我们所看到的空闲进程端口占用的特点:
          因为总是有程序要交替或者分段连续地访问网络,而且同一个程序在端口被完全释放之前,可能还会再次使用,就算不再使用,为了保证正确通信,也要等待两个MSL,故处于Time_Wait。因此我们看到的情况是,系统空闲进程占用了一些端口,而且这些端口、端口的数量随着每次执行netstat -a -n -o命令时也会有变化。因为可能在某个处于Time_Wait的端口被完全释放之前,又有一个连接不再需要某个端口了,故新的一个端口又被置于Time_Wait状态,过了不久,前一个终于被释放了,于是您还是看到有这样的状态,但是端口是不一样的。对于一个接入网络并且安装了需要网络的应用软件的操作系统,这个过程是无限循环的,因此您总是能够看到处于Time_Wait状态的被PID=0的系统空闲进程“使用”的连接。

以下是使用C语言实现单处理器系统进程调度的代码示例: ``` #include <stdio.h> #include <stdlib.h> #define MAX_PROCESS 10 #define TIME_SLICE 2 int current_time = 0; // 当前时间 int current_process = -1; // 当前正在运行的进程的编号 // 进程控制块结构体 typedef struct PCB { int pid; // 进程编号 int status; // 进程状态:0-空闲,1-就绪,2-运行,3-阻塞,4-完成 int arrival_time; // 进程到达时间 int burst_time; // 进程执行时间 int remaining_time; // 进程剩余执行时间 int wait_time; // 进程等待时间 } PCB; PCB process_table[MAX_PROCESS]; // 进程表 // 创建进程 void create_process(int pid, int arrival_time, int burst_time) { process_table[pid].pid = pid; process_table[pid].status = 0; process_table[pid].arrival_time = arrival_time; process_table[pid].burst_time = burst_time; process_table[pid].remaining_time = burst_time; process_table[pid].wait_time = 0; } // 进程调度 void schedule() { int i; // 找到最早到达的就绪进程 int earliest_ready = -1; for (i = 0; i < MAX_PROCESS; i++) { if (process_table[i].status == 1) { // 就绪状态 if (earliest_ready == -1 || process_table[i].arrival_time < process_table[earliest_ready].arrival_time) { earliest_ready = i; } } } if (current_process != -1 && process_table[current_process].remaining_time > 0) { // 当前进程未完成 process_table[current_process].status = 1; // 放回就绪队列 } if (earliest_ready != -1) { // 有就绪进程 current_process = earliest_ready; process_table[current_process].status = 2; // 运行状态 process_table[current_process].wait_time += current_time - process_table[current_process].arrival_time; // 计算等待时间 } else { // 无就绪进程 current_process = -1; } } // 进程阻塞 void block_process(int pid) { process_table[pid].status = 3; // 阻塞状态 } // 进程唤醒 void wakeup_process(int pid) { process_table[pid].status = 1; // 就绪状态 } // 主函数 int main() { int i, j; // 初始化进程表 for (i = 0; i < MAX_PROCESS; i++) { process_table[i].pid = i; process_table[i].status = 0; process_table[i].arrival_time = -1; process_table[i].burst_time = -1; process_table[i].remaining_time = -1; process_table[i].wait_time = -1; } // 创建进程 create_process(0, 0, 3); create_process(1, 1, 5); create_process(2, 2, 2); create_process(3, 3, 4); create_process(4, 4, 6); // 进程调度 while (1) { int all_done = 1; // 是否所有进程均已完成 for (i = 0; i < MAX_PROCESS; i++) { if (process_table[i].status != 4) { // 进程未完成 all_done = 0; break; } } if (all_done) { // 所有进程均已完成 break; } schedule(); if (current_process != -1) { printf("时间 %d,进程 %d 开始执行\n", current_time, current_process); for (j = 0; j < TIME_SLICE; j++) { current_time++; process_table[current_process].remaining_time--; if (process_table[current_process].remaining_time == 0) { // 进程完成 process_table[current_process].status = 4; // 完成状态 printf("时间 %d,进程 %d 完成\n", current_time, current_process); break; } } if (process_table[current_process].remaining_time > 0) { // 时间片用完,进程被抢占 printf("时间 %d,进程 %d 时间片用完,被抢占\n", current_time, current_process); process_table[current_process].status = 1; // 放回就绪队列 } } else { current_time++; } } // 输出进程等待时间 printf("进程等待时间:\n"); for (i = 0; i < MAX_PROCESS; i++) { printf("进程 %d:%d\n", i, process_table[i].wait_time); } return 0; } ``` 该程序使用时间片轮转法调度策略,每个进程被分配一个时间片,时间片用完后进程被抢占并放回就绪队列。进程表中的状态分别为0-空闲,1-就绪,2-运行,3-阻塞,4-完成。在主函数中创建了5个进程,分别为: 进程0,到达时间0,执行时间3 进程1,到达时间1,执行时间5 进程2,到达时间2,执行时间2 进程3,到达时间3,执行时间4 进程4,到达时间4,执行时间6 程序输出了每个进程开始执行和完成的时间,并在程序结束后输出了每个进程的等待时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值