Linux之进程与线程

一、进程控制

首先了解CPU时间片的概念:

CPU 会给每个进程被分配一个时间段,进程得到这个时间片之后才可以运行,使各个程序从表面上看是同时进行的。如果在时间片结束时进程还在运行,CPU 的使用权将被收回,该进程将会被中断挂起等待下一个时间片。如果进程在时间片结束前阻塞或结束,则 CPU 当即进行切换,这样就可以避免 CPU 资源的浪费。

进程的创建:

进程的ID为pid_t类型,本质是一个正整数

包含的头文件:

#include<sys/types.h>

#include<unistd.h>

相关操作:

获取当前进程ID(PID):

pid_t getpid(void)

获取当前进程的父进程ID(PPID):

pid_t getppid(void)

创建一个新的进程:

pid_t fork(void)

这里主要解析fork函数:

fork函数调用成功之后,会返回两个值,父子进程之间的返回值是不同的。

父进程的虚拟地址空间将该返回值标记为一个大于0的数(其实记录的就是子进程的ID)

子进程的虚拟地址空间中将该返回值标记0

在程序中一般是通过fork的返回值来判断当前进程是父进程还是子进程

示例:

int main()
{
    // 在父进程中创建子进程
    pid_t pid = fork();
    printf("当前进程fork()的返回值: %d\n", pid);
    if(pid > 0)
    {
        // 父进程执行的逻辑
        printf("我是父进程, pid = %d\n", getpid());
    }
    else if(pid == 0)
    {
        // 子进程执行的逻辑
        printf("我是子进程, pid = %d, 我爹是: %d\n", getpid(), getppid());
    }
    else // pid == -1
    {
        // 创建子进程失败了
    }
    
    // 不加判断, 父子进程都会执行这个循环
    for(int i=0; i<5; ++i)
    {
        printf("%d\n", i);
    }
    
    return 0;
}

循环创建进程:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main()
{
    pid_t pid;
    // 在循环中创建子进程
    for(int i=0; i<3; ++i)
    {
        pid = fork();
        if(pid > 0)
        {
            sleep(3);
        }
        else if(pid == 0)
        {
            // 不让子进程执行循环, 直接跳出
            break;
        }
    }
    printf("当前进程pid: %d\n", getpid());
    return 0;
}


需要注意的是:

两个进程中是不能通过全局变量实现数据交互的,因为每个进程都有自己的地址空间,两个同名全局变量存储在不同的虚拟地址空间中,二者没有任何关联性。如果要进行进程间通信需要使用:管道,共享内存,本地套接字,内存映射区,消息队列等方式。

exec族函数:

需求:需要通过一个进程启动另外一个进程,那么这种情况下需要使用exec族函数

函数原型:

#include <unistd.h>

extern char **environ;
int execl(const char *path, const char *arg, ...
          /* (char  *) NULL */);
int execlp(const char *file, const char *arg, ...
           /* (char  *) NULL */);
int execle(const char *path, const char *arg, ...
           /*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
            char *const envp[]);

execl():

该函数可用于执行任意一个可执行程序,函数需要通过指定的文件路径才能找到这个可执行程序

#include<unistd.h>
int execl(const char* path,const char* arg,....)

参数:

path:要启动的可执行程序的路径

arg: 启动的进程的名字,可以随意指定,一般和要启动的可执行程序名相同

....:要执行的命令需要的参数,可以写多个,最后以 NULL 结尾,表示参数指定完了。
返回值:如果这个函数执行成功,没有返回值,如果执行失败,返回 -1

execlp()函数:

该函数常用于执行已经设置了环境变量的可执行程序,函数中的 p 就是 path,也是说这个函数会自动搜索系统的环境变量 PATH,因此使用这个函数执行可执行程序不需要指定路径,只需要指定出名字即可。

int execlp(const char *file, const char *arg, ...);

参数:
file: 可执行程序的名字
在环境变量 PATH 中,可执行程序可以不加路径
没有在环境变量 PATH 中,可执行程序需要指定绝对路径
arg: 启动的进程的名字,可以随意指定,一般和要启动的可执行程序名相同
... : 要执行的命令需要的参数,可以写多个,最后以 NULL 结尾,表示参数指定完了。
返回值:如果这个函数执行成功,没有返回值,如果执行失败,返回 -1

函数的使用:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值