Linux下的进程

定义:进程是一个具有一定独立功能的程序的一次运行活动,同时也是资源分配的最小单元;

进程与程序的区别:

进程是动态的,程序是静态的:程序是有序代码的集合;进程是程序的执行。通常进程不可在计算机之间迁移;而程序通常对应着文件、静态和可以复制

进程是暂时的,程序使长久的:进程是一个状态变化的过程,程序可长久保存

进程与程序组成不同:进程的组成包括程序、数据和进程控制块(即进程状态信息)

进程与程序的对应关系:通过多次执行,一个程序可对应多个进程;通过调用关系,一个进程可包括多个程序。

进程的状态:

执行状态:进程正在占用CPU

就绪状态:进程已具备一切条件,正在等待分配CPU的处理时间片

等待状态:进程不能使用CPU,若等待事件发生则可将其唤醒

1.创建一个进程:

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

int main()
{
    pid_t pid;

    pid = fork();//创建一个进程,一般有三种返回值
    if(-1 == pid)
    {
        perror("fork");
        exit(1);
    }
    else if(0 == pid)//子进程创建成功,子进程和父进程同时进行,先后顺序不一定
    {
        printf("This is child! pid: %d\n", getpid());//getpid()获取进程号
        printf("ppid: %d\n", getppid());//getppid()获取父进程的进程号
    }
    else//父进程返回子进程的进程号
    {
        printf("This is parent! pid %d\n", getpid());
        printf("pid : %d\n", pid);//返回子进程的进程号
    }
    return 0;
}

2.fork()创建一个子进程的时候,写实拷贝父进程的内存空间,即一个G的内核空间,3个G 的用户空间

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

int main()
{
    pid_t pid;
    int a = 0;

    pid = fork();
    if(-1 == pid)
    {
        perror("fork");
        exit(1);
    }
    else if(0 == pid)
    {
        a++;
        printf("child a:%d, %p", a, &a);//输出a=1
    }
    else
    {
        a++;
        printf("parent a:%d, %p", a, &a);//输出a=1
    }

    //两个a的地址相同,子进程写时拷贝父进程的内存空间,两个a是不同的a 
    return 0;
}

3.实现子进程写,父进程读

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

int main()
{
    pid_t pid;
    int fd, ret;
    char buf[32] = {0};

    fd = open("hello.txt", O_CREAT | O_RDWR | O_EXCL, 00700);//创建并打开一个文件

    pid = fork();
    if(-1 == pid)
    {
        perror("fork");
        exit(1);
    }
    else if(0 == pid)
    {
        scanf("%s", buf);
        ret = write(fd, buf, strlen(buf));
        if(-1 == ret)
        {
            perror("write");
            exit(1);
        }
    }
    else
    {
        sleep(5);//子进程和父进程是并发执行的,scanf还没输入完父进程已经结束了,所以要睡眠几秒
        lseek(fd, 0, SEEK_SET);
        memset(buf, 0, sizeof(buf));
        ret = read(fd, buf, sizeof(buf));//此时buf已经清空了,所以不能用strlen
        if(-1 == ret)
        {
            perror("read");
            exit(1);
        }
    }
    return 0;
}

4.回收子进程wait()

孤儿进程:子进程还没结束,父进程先结束了

僵尸进程:父进程没有回收子进程的资源

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

int main()
{
    pid_t pid;

    pid = fork();
    if(-1 == pid)
    {
        perror("fork");
        exit(1);
    }
    else if(0 == pid)
    {
        printf("child\n");
    }
    else
    {
        printf("parent!\n");
        int status;
        wait(&status);//1.等待子进程结束 2.回收子进程的资源
        //waitpid(pid, &status, 0);
    }
    return 0;
}

5.创建子进程的另一种方法vfork()

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

int main()
{    
    pid_t pid;
    int a = 0;

    pid = vfork();
    if(-1 == pid)
    {
        perror("vfork");
        exit(1);
    }
    else if(0 == pid)//此时一定是子进程先运行完再运行父进程
    {
        a++;
        printf("This is child! a: %d, %p\n", a, &a);
        sleep(2);
        exit(1);//此时一定要指明退出状态
    }
    else
    {
        a++;
        printf("This is parent! a: %d, %p\n", a, &a);
    }

    //此时两个a的值不同,地址也相同,因为vfork()创建的子进程和父进程共享内存空间
    return 0;
}

6.execl()函数

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

int main()
{
    pid_t pid;
    
    pid = fork();
    if(-1 == pid)
    {
        perror("fork");
        exit(1);
    }
    else if(0 == pid)
    {
        printf("This is child!\n");
        execl("/bin/ls", "-a", "-l", NULL);//调用另一个进程ls
    }
    else
    {
        printf("This is parent!\n");
    }
    return 0;
}

7.信号的使用

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <signal.h>

void handlder(int sig)
{
    printf("hello %d\n", sig);//sig代表的是SIGINT 宏定义为2
}

int main()
{
    //signal(SIGINT, SIG_IGN);//忽视Ctrl C 

    signal(SIGINT, handlder);//handlfer是一个函数指针
    while(1);

    return 0;
}

//闹钟信号
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <signal.h>

void handlder(int sig)
{
    printf("hello\n");
    alarm(1);
}

int main()
{
    alarm(1);//1s后给进程发送SIGALRM信号,有效期一次
    signal(SIGALRM, handlder);
    while(1);//进程不能结束

    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值