*******************************进程控制编程***************************************
#进程的定义:
进程是一个具有一定独立功能的程序的一次运动活动,同时也是资源分配的最小单元。
#程序是放到磁盘的可执行文件
#进程是指程序执行的实例
#进程和程序的区别
1.进程是动态的,程序是静态的
2.进程是暂时的,程序是长久的
3.进程与程序组成不同
4.进程与程序的对应关系:通过多次执行,一个程序可对应多个进程;通过调用关系,一个程序可以对应多个进程。
#*进程的生命周期
1.创建:每个进程都是由父进程创建,进程可以创建子进程,子进程又可以创建子进程的子进程。
2.运行:多个进程可以同时存在,进程间可以通信。
3.撤销:进程可以被撤销,从而结束一个进程的运行。
#*进程的状态
1.执行状态:进程正在占用CPU
2.就绪状态:进程已具备一切条件,正在等待分配CPU的处理时间片
3.等待状态:进程不能使用CPU,若等待事件发生则可将其唤醒
#Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点。
也就是说,每个进程都是一个独立的运行单位,拥有各自的权力和责任。
进程具有健壮性。
#进程ID(PID):表示进程的唯一数字
父进程的ID(PPID)
启动进程的ID(UID)
#进程互斥:
进程互斥是指当有若干进程都要使用某一共享资源时,任何时刻最多允许一个进程使用,其他要使用该资源的进程必须等待,直到占用该资源者释放了该资源为止。
#临界资源
操作系统中将一次只允许一个进程。
#临界区
进程中访问临界资源的那一段程序代码成为临界区。
#进程同步
一组并发进程按一定的顺序执行的过程称为进程间的同步。
#*进程调度
概念:按一定算法,从一组待运行的进程中选出一个来占有CPU运行。
调度方式:
1.抢占式 2.非抢占式
#调度算法
1.先来先服务调度算法
2.短进程优先调度算法
3.高优先级优先调度算法
4.时间片轮转法
#死锁:
多个进程因竞争资源而形成一种僵局,若无外力作用,这些进程都将永远不能再向前推进
#1.
#include
#include
#include
int main()
{
printf("%d\n",getpid()); //子进程号
printf("%d\n",getppid()); //父进程号
while(1);
return 0;
}
#fork
创建子进程
fork它被调用一次,却返回两次,它可能有三种不同的返回值
父进程返回子进程的ID,子进程返回0
fork 子进程复制父进程的地址空间
子进程可以继承父进程已经打开的文件描述符
#2.
#include
#include
#include
#include
int main()
{
int a = 0;
pid_t pid;
pid = fork();
if( -1 == pid )
{
perror("fork");
exit(1);
}
else if( 0 == pid )
{
a++;
printf("a = %d\n",a);
printf("a = %p\n",&a);
printf("this is childprocess, pid:%d,ppid:%d\n",getpid(),getppid());
printf("%d\n",pid);
}
else
{
a++;
printf("a = %d\n",a);
printf("a = %p\n",&a);
printf("this is parentprocess,pid:%d\n",getpid());
printf("%d\n",pid);
}
return 0;
}
#vfork
创建子进程
并且子进程先运行完成后父进程才会开始运行。
子进程和父进程共享数据。
#3.
#include
#include
#include
#include
int main()
{
int a = 0;
pid_t pid;
pid = vfork();
if( -1 == pid )
{
perror("vfork");
exit(1);
}
else if( 0 == pid )
{
a++;
printf("this is childprocess! a = %d\n",a);
exit(1);
}
else
{
a++;
printf("this is parentprocess! a = %d\n",a);
}
return 0;
}
#exec函数族
exec启动一个毫不相关的进程。
#4-1
#include
#include
#include
#include
int main()
{
pid_t pid;
pid = vfork();
if( -1 == pid )
{
perror("vfork");
exit(1);
}
else if( 0 == pid )
{
execl("/mnt/hgfs/share/zq/FILE/test","./test","hello","world","i","hate","you","!",NULL);
//exit(1);
}
else
{
printf("this is parentprocess!\n %d",getpid());
}
}
#4-2
#include
int main(int argc, char* argv[])
{
int i;
printf("%d\n",getpid());
for(i = 1; i < argc ; i++)
{
printf("%s\n",argv[i]);
}
return 0;
}
#wait
1.等待子进程结束(阻塞)
2.回收子进程资源
注意点:任意一个子进程结束,父进程也会结束。
#include
#include
#include
#include
#include
int main()
{
int a = 0;
pid_t pid;
pid = fork();
if( -1 == pid )
{
perror("fork");
exit(1);
}
else if( 0 == pid )
{
sleep(1);
printf("this is childprocess, pid:%d,ppid:%d\n",getpid(),getppid());
exit(0);
}
else
{
int status;
printf("this is parentprocess,pid:%d\n",getpid());
wait(&status);
if( WIFEXITED (status) )
{
printf("childprocess has been normally quit! %d\n",WEXITSTATUS(status));
}
}
return 0;
}
#waitpid
注意:指定等待一个子进程结束
#exit,_exit用于终止进程
区别:
_exit:直接是进程停止,清楚其使用的内存,并清除缓冲区的内容。
#include
#include
void print(int num)
{
printf("please kill meeeeeeeeeeeeeeeeeeeee!!!signal:%d\n",num);
}
int main()
{
signal(2, print);
while(1);
return 0;
}
#include
#include
#include
int main()
{
int pid;
scanf("%d",pid);
kill(pid, SIGKILL);
return 0;
}
用于被杀死的test文件
#include
#include
#include
int main()
{
printf("%d\n",getpid());
while(1);
return 0;
}