进程(Linux)(C)

13 篇文章 0 订阅
  • 程序:

有序的指令集合

静态

  • 进程:

程序的一次执行过程,包含创建、运行、结束

是系统分配资源的最小单位

  • 进程的组成:

  • 正文段

来自程序的代码段,指令

  • 用户数据段

来自于程序的数据段,.data(全局变量,常量) .bass(未初始化的全局变量)

  • 系统数据段

堆栈(栈空间数据)局部变量,形参,函数返回值

寄存器

PCB进程控制块

  • 进程ID

  • 优先级

  • 进程的用户

  • 进程的分类:

  • 交互类进程

前台进程(可以由终端输入或输出的进程)

后台进程(只能对终端输出)

  • 批处理进程

不属于某个终端,只是将进程提交到某个队列以便顺序执行

  • 守护进程

由操作系统启动便开始运行的进程,操作系统关闭则终止

  • 进程的状态:

  • 运行态

运行态:拥有cpu

就绪态:准备运行

  • 等待态

可中断:有资源可回到运行态

不可中断:有资源不一定回到运行态,需要特殊条件

  • 停止态

暂停在后台(前台ctrl+z停止)

  • 僵尸态

进程结束,其资源还未回收

  • 死亡态

进程完全结束

  • 进程的调度:

  • ps:

ps -aus:查看进程详细信息

stat:进程状态

S:等待态

s:拥有子进程的进程

I(大写i):闲置在内核中的进程

N:低优先级进程

<:高优先级进程

l(小写L):拥有子线程的进程

+:运行在前台的进程

R:运行态

T:停止态

Z:僵尸态

  • top:

NI:优先级(-20 - 19,高-低)

nice:

-n 5 ./a.out(运行时按5优先级运行)

renice:

-n 10 PID(修改此进程优先级)

  • kill:向指定进程发送信号

-l:查看所有信号(共62个)

-9:杀死进程

-19:暂停进程

  • bg:将停止的状态运行到后台

+ 任务号

+ % PID

  • fg:将停止的状态运行到前台

+ 任务号

+ % PID

  • 进程的模式(执行模式):

用户模式

内核模式

  • 进程相关的系统调用:

#include <unistd.h>

pid_t fork(void);

功能:创建子进程

返回值:成功将子进程PID返回父进程中,将0返回到子进程中,失败返回-1到父进程

子进程会拷贝父进程几乎所有内容

父子进程运行区别:

父进程从main开始运行

子进程从fork(父节点当前状态)开始运行

父子进程参与统一调度,运行顺序是不一定的

一般而言子进程结束都由父进程回收资源

如果父进程先结束,子进程的资源由其他进程回收

#include <sys/types.h>

 #include <unistd.h>

 pid_t vfork(void);

功能:创建子进程

返回值:成功将子进程PID返回父进程中,将0返回到子进程中,失败返回-1到父进程

区别:vfork子进程结束后父进程才开始执行,而fork顺序不一定

#include <unistd.h>

pid_t getpid(void);//获得当前进程PID

pid_t getppid(void);//获得父进程PID

exec函数族(进程内容替换,运行其他可执行文件,PID不会变)

#include <unistd.h>

extern char **environ;

int execl(const char *pathname, const char *arg, .../* (char *) NULL */);

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

int execle(const char *pathname, const char *arg, ... /*, (char *) NULL, char *const envp[] */);

int execv(const char *pathname, char *const argv[]);

int execvp(const char *file, char *const argv[]);

int execvpe(const char *file, char *const argv[], char *const envp[]);

pathname:路径名

file:文件名(execlp与execvp是以系统环境变量为运行的地址,可执行文件需在bin中)

arg:命令及其参数(“命令”,“参数”)

NULL:结尾

envp:存储环境变量的指针数组

l:以列表的形式

v:以容器的形式

运行错误返回-1

#include <stdlib.h>

void exit(int status);

功能:当前进程退出

status:进程退出时的状态值,0为正常结束

#include <unistd.h>

void _exit(int status);

功能:当前进程退出

status:进程退出时的状态值,0为正常结束

区别:标准库调用和系统调用

_exit在结束进程时不会刷新缓冲区内容,而exit会刷新缓冲区

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int *wstatus);

功能:进程阻塞等待子进程结束

返回值:成功返回退出子进程的PID,失败返回-1

wstatus:获取子进程退出的状态值

查看进程退出状态值的宏函数

WEXITSTATUS(wstatus)//等同((wstatus >> 8) & 0xff,返回子进程exit中的值)

查看进程是否正常退出

WIFEXITED(wstatus)//等同(wstatus & 0x7f,若正常退出,为0;若异常退出,返回相应异常信号)

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

功能:处理子进程

返回值:成功option为0时,返回退出的子进程pid;option为WNOHANG,没有子进程返回0,有则返回PID。失败返回-1

pid:>0等待指定进程pid,-1等待任意子进程退出,<-1等待其组ID等于pid的绝对值的任一子进程,0等待其组ID等于pid的任一子进程

wstatus:获取子进程退出的状态值

option:0:阻塞等待进程结束,WNOHANG:非阻塞处理子进程退出(若没有子进程退出,会立即返回,若子进程退出则处理资源)

  • 守护进程

在linux系统启动时就会开始运行的进程,当系统关闭时结束,实际工作为周期性完成某些特定操作

daemo守护进程:不属于某个终端,也是一个后台jinc

  1. 创建子进程,结束父进程,子进程将变为后台进程

  1. 摆脱终端,创建一个新的会话组,并使得该子进程成为该会话组的组长

#include <sys/types.h>

#include <unistd.h>

pid_t setsid(void);

返回值:成功为sid会话号,失败为-1

  1. 改变该进程的工作目录,建议修改为根目录

#include <unistd.h>

int chdir(const char *path);

path:文件夹路径

返回值:成功为0,失败为-1

  1. 重设文件掩码

#include <sys/types.h>

#include <sys/stat.h>

mode_t umask(mode_t mask);

mask:重设的掩码值

  1. 关闭所有以打开文件描述符

#include <unistd.h>

int getdtablesize(void);

返回值:当前的文件描述符的最大值

  1. 守护进程相关功能

由自己定义

  • 部分代码示例

//fork 创建进程
#include <stdio.h>
#include <unistd.h>
void fun01()
{
    while(1)
    {
        printf("child process\n");
        sleep(1);
    }
}
void fun02()
{
    while(1)
    {
        printf("parent process\n");
        sleep(1);
    }
}
int main(int argc, char *argv[])
{
    int pid = fork();
    if(pid<0)
    {
        perror("fork");
        return -1;
    }
    if(pid==0)
    {
        fun01();
    }else
    {
        fun02();
    }
    return 0;
} 
//exec
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{ 
    printf("Run:\n");
    execl("/bin/ls","ls","-l",NULL);

    /*char *a[]={"ls",NULL};
    execv("/bin/ls",a);*/
    return 0;
} 
//wait
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{ 
    pid_t pid = fork();
    if(pid==0)
    {
        printf("Im child pid=%d\n",getpid());
        sleep(1);
        exit(10);
    }
    else
    {
        int status;
        int cpid=wait(&status);
        printf("Im parent cpid=%d status=%d\n",cpid,WEXITSTATUS(status));
    }
    return 0;
} 
//waitpid
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{ 
    pid_t pid = fork();
    if(pid==0)
    {
        sleep(1);
        printf("Im child\n");
        exit(10);
    }
    else
    {
        int status;
        int cpid=waitpid(-1,&status,0);
        printf("Im parent cpid=%d status=%d",cpid,WEXITSTATUS(status));
    }
    return 0;
} 
//创建守护进程
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{ 
    //创建子进程,并让它成为后台进程
    pid_t pid = fork();
    if(-1 == pid)
    {
        perror("fork is fail");
        exit(-1);
    }
    else if(0 == pid)
    {
        //创建会话组,并成为会话组组长
        pid_t sid = setsid();
        if(-1 == sid)
        {
            perror("sid is fail");
            exit(-1);
        }
        //修改工作目录
        int ret = chdir("/");
        if(-1 == ret)
        {
            perror("chdir is fail");
            exit(-1);
        }
        //修改文件掩码
        umask(0);
        //关闭所有以打开的文件描述符
        int num = getdtablesize();
        for(int i = 0;i<num;i++)
        {
            close(i);
        }
        //守护进程功能
        FILE *fp = fopen("/home/hqyj/zz/process/1.txt","r+");
        while(1)
        {
            sleep(1);
            time_t m_time = time(NULL);
            struct tm *p = localtime(&m_time);
            char buf[1024]={0};
            sprintf(buf,"%d/%d/%d %d:%d:%d\n",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
            fwrite(buf,sizeof(buf),1,fp);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值