学习linuxC编程实战-----linux进程控制

9 篇文章 0 订阅
2 篇文章 0 订阅
 Linux进程
进程是操作系统资源管理的最小单位。是一个动态的实体,是程序的一次执行过程。
进程是动态的,程序是静态的;
为了在同一时间内能执行更多的任务,进程内部又可划分了许多的线程。
线程在进程内部,是比进程更小的能独立运行的基本单位。线程基本上不拥有系统资源,它与同属于一个进程的其他线程共享进程拥有的全部资源。
linux下可通过命令ps或pstree查看当前系统的进程。

进程的标识
每个进程都是通过唯一 的进程ID标识的。非负数,每个进程除了进程ID外还有其它的标识符信息,都可以通过相应的函数获得。这些函数的声明在 unistd.h 头文件中。
 
获取进程各种标识符的函数


pid_t getpid(id)      //获得进程ID
pid_t getppid(id)    //获得进程父进程ID
pid_t getuid()        //获得进程的实际用户ID
pid_t geteuid()        //获得进程的有效用户ID    
pid_t getgid()        //获得进程的实际组ID
pid_t getegid(id)    //获得进程的有效组ID


实际用户ID(uid):标识运行该进程的用户。
有效用户ID(euid):标识以什么用户身份来运行进程。如:普通用户A,运行了个程序,是以root身份来运行的,这个程序运行时就具有root权限。此时实际用户ID是A用户的ID,而有效用户ID是root用户ID。
实际组ID(gid):实际用户所属的组的组ID。
有效组ID(egid):有效组ID是有效用户所属的组的组ID。

linux进程状态
运行状态R(runnbale)
可中断等待状态S(sleeping)
不可中断等待状态D(uninterruptible sleep)
僵死状态Z(zombile)
停止状态T(traced or stopped)
<(高优先级进程),N(低优先级进程),L(内存锁页面,即页面不可以被换出内存),s(该进程为会话首进程),l(多线程进程),+(进程位于前台进程组)。

进程控制


主要的系统调用有
fork:用于创建一个新进程
exit:用于终止一个应用程序。
exec:用于执行一个应用程序。
wait:将父进程挂起,等待子进程终止。
getpid:获取当前进程的进程ID。
nice:改变进程的优先级。

进程的创建两种方式
一、由操作系统创建。平等的
二、由父进程创建。继承的

系统调用fork是创建一个新进程的唯一方法,除了极少数以特殊方式创建的进程。如:init

创建一个子进程之后,父进程和子进程争夺CPU,抢到的执行,另一个挂起等待。
如果想要父进程等待子进程执行完毕以后在继续执行,可以在fork操作之后调用wait或waitpid。

#inlcude<sys/types.h>
#inlcude<unistd.h>
pid_t fork(void);

fork函数调用一次返回两次,父进程返回值为新创建的子进程的进程ID  子进程I返回值为0,


fork.c

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
    pid_t pid;
    printf("Process Creation Study\n");
    pid=fork();
    switch(pid)
    {
        case 0:
            printf("Child process is running ,Current Pid is %d,ParentPid is %d\n",pid,getppid());
            break;
        case -1:
            perror("Process creation failed\n");
            break;
        default:
            printf("Patent process is running , ChildPid is %d,Parentpid is %d\n",pid,getpid());
            break;
    }
    exit(0);
}


fork2.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
    pid_t pid;
    char *msg;
    int k;
    printf("Process Creation Study\n");
    pid=fork();
    switch(pid)
    {
        case 0:
            msg="Child process is running ";
            k=3;
            break;
        case -1:
            preeor("Process creation failed\n");
            break;
        default:
            msg="Parent process is running ";
            k=5;
            break;
    }
    while(k>0)
    {
        puts(msg);
        sleep(1);
        k--;
    }
    exit(0);
}    

孤儿进程
如果一个子进程的父进程先于子进程结束,子进程就成为一个孤儿进程,它有init进程收养,成为init进程的子进程。
fork3.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
    pid_t pid;
    pid=fork();
    switch(pid)
    {
        case 0:
            while(1)
            {
                printf("A background process,PID:%d\n,Parent ID:%d\n",getpid(),getppid());
                sleep(3);
            }
        case -1:
            perror("Process creation failed\n");
            exit(-1);
        default:
            printf("I am parent process ,my pid is %d\n",getpid());
            exit(0);
    }
    return 0;
}


vfork函数

也可以创建一个新进程,于fork的异同
1、都是调用一次返回两次。
2、使用fork创建一个子进程时,子进程只是完全复制父进程的资源。这样得到的子进程独立于父进程,有良好的并发性。而使用vfork创建的子进程时,操作系统并不将父进程的地址空间完全复制到子进程,用vfork创建的子进程共享父进程的地址空间,子进程的运行完全在父进程地址空间上。
子进程对该地址空间中任何数据的修改同样为父进程所见。
3、使用fork创建一个子进程是,是那个进程先运行取决于系统的调度算法。而vfork一个进程时,vfork保证子进程先运行,当它调用exec或exit之后,父进程才可能被调度运行。如果在调用exec或exit之前子进程要依赖父进程的某个行为,就会导致死锁。

创建守护进程

守护进程(daemon)指在后台运行的没有控制终端与之相连的进程。独立于控制终端,通常周期性的执行某种任务。linux中的大多数服务器就是用守护进程的方式实现的。在后台运行。

启动方式:
linux系统启动时从启动脚本/etc/rc.d中启动
有作业规划进程crond启动
由用户终端执行


daemon.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<sys/param.h>
#include<sys/stat.h>
#include<time.h>
#include<syslog.h>
int init_datmon(void)
{
    int pid;
    int i;
    ..................
    .......
}



进程退出
(1)正常退出
在main函数中执行return。
调用exit函数。
调用_exit函数。
(2)异常退出
调用about函数。
进程收到某个信号,而该信号是程序终止。

不管那种退出方式,最终都会执行内核中的同一段代码。这段代码用来关闭进程所有已打开的文件描述符,释放它所有占用的内存和其他资源。

各种退出方式的比较:
a、exit和return的区别:exit是一个函数,有参数;而return是函数执行完后的返回。exit把控制权交给系统,而return将控制权交给调用函数。
b、exit和about的区别:exit是正常终止进程,而about是异常终止。
c、exit(int exit_code):exit中的参数exit_code为0代表进程正常终止,若为其他值表示程序执行过程中有错误发生
d、exit()和_exit()的区别:exit在头文件stdlib.h中声明,而_exit()声明在头文件unistd.h中
两个函数都能正常终止进程,但是_exit()会执行后立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值