进程状态
R:运行态 运行中或队列中
S:睡眠 可中断睡眠,在等待事件完成
D:磁盘休眠 不可中断睡眠态,等待I/O结束
T:停止 收到SIGSTOP进入T,收到SIGCOUT运行
X:死亡 只是一个返回状态,列表看不到
进程间通信
1.管道
- 匿名管道
半双工,在具有亲缘关系的进程间通信; - 命名管道
2.消息队列
消息队列存放于内核中,消息队列与接收发送进程相独立;
3.信号量
是一个资源计数器,用于进程之间的同步与互斥,不能用于数据通信;
4.共享内存
多个进程共享指定的储存区,是最快的IPC,因为可以多个进程通信,所以经常与信号量一起使用进行进程的同步;
进程优先级修改:
top—>按"r",输入进程PID与NI值(nice值越小,优先级越高)
fork
- fork的返回值有两个,父进程返回子进程id,子进程返回0,创建子进程失败返回-1;
- 所以在fork()后会进行分流操作。
#include<iostream>
#include<unistd.h>
using namespace std;
int main()
{
sleep(1);
cout<<"俺睡了1秒"<<endl;
cout<<getpid()<<endl;//获取当前进程pid
int ret=fork();//创建子进程,返回父进程pid
if(ret<0)
{
cout<<"fork erro"<<endl;
return 1;
}
else if(ret==0)
{
cout<<"child_id:"<<getpid()<<"ret:"<<ret<<endl;
}
else
{
cout<<"parent_id:"<<getpid()<<"ret:"<<ret<<endl;
}
return 0;
}
fork与vfork的区别
- vfork创建的子进程先于父进程运行,在子进程调用exec与exit之前父进程是不会运行的;
- fork使用写时拷贝技术,vfork父子进程共用数据段;
- vfork若在使用exec与exit之前有依赖于父进程的 操作则会死锁。
- exec:
创建子进程后,往往调用exec函数来执行另一个程序。调用exec函数进程执行的程序完全替换为新程序,从其main函数开始执行。
调用exec并不创建新进程,所以进程ID不改变。exec只是用一个全新的程序替换了当前进程的正文、数据、堆和栈段。 - 写时拷贝
内核只为新生成的子进程创建虚拟空间结构,它们复制于父进程的虚拟空间结构,但是不为这些段分配物理内存,它们共享父进程的物理空间,当父子进程中有更改相应的段的行为发生时,再为子进程相应的段分配物理空间。