Linux 进程

进程是操作系统资源管理的最小单位。

进程的概念:
进程是操作系统资源分配的基本单位。进程和程序的区别在于进程是动态的,程序是静态的,进程是运行中的程序,程序是保存在硬盘上的可执行的代码。进程内部又划分了许多线程,线程在进程内部,它是比进程更小的能独立运行的基本单位,线程基本上不拥有系统资源,它与同属于一个进程的其他线程共享进程拥有的全部资源。进程在运行过程中拥有独立的内存单元,其内部的线程共享这些内存。一个线程可以创建或撤销另一个线程,同一个进程中的多个线程可以并行执行。

进程标识:
每一个进程都有唯一的进程ID,进程ID是一个非负数,除了进程ID每个进程还有其他的标识。可以通过函数来获得:
pid_t getpid(id) 获得进程id
pid_t getppid(id) 获得进程的父进程id
pid_t getuid(id) 获得进程的实际用户id
pid_t geteuid(id) 获得进程的有效用户id
pid_t getgid(id) 获得进程的实际组id
pid_t getegid(id) 获得进程的有效组id

Linux 进程的结构:
代码段 数据段 堆栈段
代码段 存放程序的可执行代码
数据段 存放程序的全局变量、常量、静态变量
堆栈段 堆用于存放动态分配的内存变量,栈用于函数调用,存放函数参数,函数内部定义的局部变量

Linux进程状态:
可运行状态 :正在运行或在运行队列中等待运行
可中断等待状态 :进程在等待某个事件完成,等待过程中可以被信号或定时器唤醒
不可中断等待状态 :进程在等待某个事件完成,等待过程中不可以被信号或定时器唤醒
僵死状态:进程已终止,但进程描述符依旧存在直到父进程调用wait()后释放
停止状态:进程因为收到了SIGSTOP SIGSTP SIGTIN SIGOUT信号后停止运行或者该进程正在被跟踪

进程控制
fork() 用于创建一个新的进程
exit() 用于终止一个进程
exec() 用于执行一个应用程序
wait() 将父进程挂起,等待子进程终止
getpid() 获取当前进程的ID
nice() 改变进程的优先级

创建进程
fork()函数:
pid_t fork(void)
该函数有两个返回值,即调用一次返回两次。成功调用fork函数后,当前进程已经分裂为两个进程,即父进程和子进程,父子进程在调用fork的地方分开,fork函数的两个返回值,一个是父进程调用fork函数后的返回值,这个返回值的刚创建的子进程的ID,;另一个是子进程中fork函数的返回值,该返回值是0。有两个返回值的前提是进程创建成功,如果创建失败则返回-1。

  1 
  2 #include<stdio.h>
  3 #include<sys/types.h>
  4 #include<unistd.h>
  5 
  6 int main()
  7 {
  8       pid_t pid;
  9 
 10       printf("Process Cration Study\n");
 11       pid = fork();
 12       switch(pid)
 13       {
 14             case 0:
 15                 printf("Child process, childID %d, ParentID %d\n", pid, getppid());
 16                 break;
 17             case -1:
 18                 perror("Process child failed!\n");
 19                 break;
 20             default:
 21                 printf("Parent process is running, childID %d , parentID %d\n",pid,getppid());
 22                 break;
 23       }
 24       exit(0);
 25 }
~                                                                                                   
"GOver.c" 25L, 437C                                                               24,4-7       全部

两次运行程序的结果如下:
这里写图片描述

这里写图片描述

以上两次运行结果都是父进程先运行,一般情况下,fork之后是父进程先执行还是子进程先进行是不确定的,取决于内核的调度方法。我们也可以让父进程与子进程交替执行,将代码做如下修改:



 int main()
 {
       pid_t pid;
       char *msg;
       int k;

       pid = fork();
      switch(pid)
       {
             case 0:
                msg = "Child process is running!\n";
                 k = 3;
                 break;
             case -1:
                 perror("Process creation failed!\n");
                 break;
             default:
                 msg = "Parent process is running!\n";
        }
    while(k > 0)
    {
        puts(msg);
        sleep(1);
        k--;
    }
    exit(0);
} 

运行情况如下:
这里写图片描述

vfork()函数
它也可以用来创建一个进程,vfork与fork一样都是调用一次,返回两次。fork创建的子进程只是完全复制父进程的资源,子进程独立于父进程;vfork创建一个子进程共享父进程的地址空间,该子进程对该地址空间的数据的任何修改都能被父进程所见;使用fork函数创建的子进程,父子进程的执行顺序由系统的调度算法决定,但是vfork保证子进程先运行,只有它调用exec或exit后父进程才会被调度。vfork不会拷贝父进程的资源空间,大大减小了系统开销。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值