进程管理1

多任务的两种形态

        进程与线程的区别

                进程之间是相互隔离的,而线程是共享进程的空间

                进程包含线程,线程是进程的最小的执行单位,每一个进程中至少包含一个线程(主线程)

                从操作系统角度看,进程是资源分配的最小单位;线程是调度(执行)的基本单位(就好比进程是一个地区批的地,开成了一个店,这个就是进程,而线程就是在这个店里面工作的人员,必须要有一个运行的人员便是主线程)

                进程有独立的地址空间,线程共享进程的内存地址空间

        Linux下的进程管理

                Linux系统是一个多进程的系统,进程之间具有并行性、互不干扰的特点。

                 linux中进程包含PCB(进程控制块)、程序以及程序所操纵的数据结构集,可分为“代码段”、“数据段”和“堆栈段”。        

          进程状态

                 运行状态R(TASK_RUNNING)

                可中断睡眠状态S(TASK_INTERRUPTIBLE)

                不可中断睡眠状态D(TASK_UNINTERRUPTIBLE)

                暂停状态T(TASK_STOPPED或TASK_TRACED)

                僵尸状态Z(TASK_ZOMBIE)

                退出状态X(TASK_DEAD)

        init进程

                进程ID为1通常是init进程,在自举过程结束时由内核调用。 init进程绝不会终止。 它是一个普通的用户进程(与交换进程不同,它不是内核中的系统进程),但是它以超级用户特权运行。

           获取进程标识       

                #include <sys/types.h> #include <unistd.h>

                pid_t getpid(void);     返回:调用进程的进程I D

                pid_t getppid(void);     返回:调用进程的父进程I D

                uid_t getuid(void);     返回:调用进程的实际用户I D

                uid_t geteuid(void);     返回:调用进程的有效用户I D

                gid_t getpgid(void);     返回:调用进程的实际组I D

                gid_t getegid(void);     返回:调用进程的有效组I D       

        fork系统调用     

               头文件: #include <sys/types.h> #include <unistd.h>    

                返回:子进程中为0,父进程中为子进程I D,出错为-1  

                该函数主要作用是在进程中创建新的线程,且创建的线程中的代码与主线程中的代码一致,但是若直接在其中的主线程创建好几个则会创建出来2的n次方个线程

         孤儿进程           

                父进程先于子进程结束,该进程称为孤儿进程

                托孤--父进程结束子进程交互XX进程托管

        int pid = fork();    //创建子进程            fork();    这样创建的话成2的n次方
    if (pid < 0)
    {
        perror("pid error:");
    }
    else if (pid == 0)        //以下代码为子进程逻辑
    {
        printf("子进程:pid = %d,ppid = %d\n", getpid(), getppid());
        for (int i = 0; i < 10; i++)
        {
            printf("子进程运行中\n");
            sleep(1);
        }
        printf("子进程运行结束\n");
    }
    else
    {
        /*int status = 0;
        int cid = wait(&status);
        printf("已结束的子进程id:%d\n", cid);*/
        printf("父进程:pid = %d,ppid = %d\n", getpid(), getppid());
        for (int i = 0; i < 5; i++)
        {
            printf("父进程运行中\n");
            sleep(1);
        }
        printf("父进程运行结束\n");
    }

     

        僵尸进程

                子进程先于父进程结束,但子进程资源没有被释放,依然被占用内存,从而产生内存泄露风险

int pid = fork();    //创建子进程            fork();    这样创建的话成2的n次方
    if (pid < 0)
    {
        perror("pid error:");
    }
    else if (pid == 0)        //以下代码为子进程逻辑
    {
        printf("子进程:pid = %d,ppid = %d\n", getpid(), getppid());
        for (int i = 0; i < 5; i++)
        {
            printf("子进程运行中\n");
            sleep(1);
        }
        printf("子进程运行结束\n");
    }
    else
    {
        /*int status = 0;
        int cid = wait(&status);
        printf("已结束的子进程id:%d\n", cid);*/
        printf("父进程:pid = %d,ppid = %d\n", getpid(), getppid());
        for (int i = 0; i < 10; i++)
        {
            printf("父进程运行中\n");
            sleep(1);
        }
        printf("父进程运行结束\n");
    }

         wait和waitpid函数

                wait函数

#include <sys/types.h> #include <sys/wait.h> pid_t wait(int * status) ; 两个函数返回:若成功则为子进程I D号,若出错则为-1. Status选项,为空时,代表任意状态结束的子进程,若不为空,则代表指定状态结束的子进程。

                阻塞(如果其所有子进程都还在运行)。 带子进程的终止状态立即返回(如果一个子进程已终止,正等待父进程存取其终止状态)。 出错立即返回(如果它没有任何子进程)。

void test1()

{

int pid = fork();    //创建子进程            fork();    这样创建的话成2的n次方
    if (pid < 0)
    {
        perror("pid error:");
    }
    else if (pid == 0)        //以下代码为子进程逻辑
    {
        printf("子进程:pid = %d,ppid = %d\n", getpid(), getppid());
        for (int i = 0; i < 5; i++)
        {
            printf("子进程运行中\n");
            sleep(1);
        }
        printf("子进程运行结束\n");
    }
    else
    {
        int status = 0;
        int cid = wait(&status);
        printf("已结束的子进程id:%d,%d\n", cid, WEXITSTATUS(status));
        printf("父进程:pid = %d,ppid = %d\n", getpid(), getppid());
        for (int i = 0; i < 10; i++)
        {
            printf("父进程运行中\n");
            sleep(1);
        }
        printf("父进程运行结束\n");
    }

}

该函数是先让子进程的内容运行完毕之后在运行主线程的内容

                waitpid函数

                pid_t waitpid(pid_t pid, int * status, int             options) ;

对于waitpid的p i d参数的解释与其值有关:

pid == -1 等待任一子进程。于是在这一功能方面waitpid与wait等效。

pid > 0 等待其进程I D与p i d相等的子进程。

pid == 0 等待其组I D等于调用进程的组I D的任一子进程。

pid < -1 等待其组I D等于p i d的绝对值的任一子进程。

void test2()
{
    //创建第一个子进程
    int pid1 = fork();
    if (pid1 < 0)
    {
        perror("pid error:");
    }
    else if (pid1 == 0)
    {
        for (int i = 0; i < 3; i++)
        {
            printf("子进程1正在运行\n");
            sleep(1);
        }
        printf("子进程1运行结束\n");
    }
    else
    {
        //创建第二个子进程
        int pid2 = fork();
        if (pid2 == 0)
        {
            for (int i = 0; i < 5; i++)
            {
                printf("子进程2正在运行\n");
                sleep(1);
            }
            printf("子进程2运行结束\n");
            exit(123);
        }
        else
        {
            int status = 0;
            while (1)
            {
                int cid = waitpid(pid2, &status, WNOHANG);
                if (cid > 0)
                {
                    printf("进程结束%d\n", WEXITSTATUS(status));

                }
            }
        }
    }
}

主线程和子线程可以同时运行,但是只检测一次因此可以放在循环当中检测

     

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值