[linux专题]基于linux进程编程

目录

1.linux进程

1.1 基本知识

2 进程编程

2.1 创建进程

2.2 创建守护进程

2.3 退出进程

2.4 执行进程程序

2.5 等待进程结束

2.6 进程id


1.linux进程

1.1 基本知识

进程是操作系统分配资源的基本单位,是一个动态的实体;

 

2 进程编程

2.1 创建进程

创建进程有两种方式,一种是操作系统创建如init进程,一种是父进程创建。区别在于,操作系统创建的进程,一般不存在隶属关系,而父进程创建的,存在隶属关系。

创建进程的函数主要有,fork 和 vfork,区别在于fork创建的进程,完全复制父进程的资源,而vfork创建的集成,共享父进程的地址空间,也就是说,子进程对地址空间的数据修改,父进程是可见的。 同时vfork 必须的子进程先运行,exit、exec后,父进程才会调用。

/*fork 和 vfork 对比,创建处分别注释,编译运行 即可看见差异*/

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

#define COMPILE_FORK
//#define COMPILE_VFORK  二选一

int g_var = 10;

int main(void)
{
    pid_t pid;
    int i;
    int var = 1;

    printf("vfork fork compare code \r\n");

#ifdef COMPILE_FORK
    pid = fork(); /*fork 方式*/
#endif

#ifdef COMPILE_VFORK
    pid = vfork(); /*vfork 方式*/
#endif   
    
    switch(pid)
    {
        case 0: /*child*/
        {
            i = 3;
            while(i-- > 0)
            {
                printf("child process running \r\n");
                g_var++;
                var++;
                sleep(1);  /*仅仅调试用*/
            }
            printf("child g_var:%d var:%d \r\n",g_var,var);
            break;
        }
        case -1: /*failed*/
        {
            perror("failed create process\n");
            exit(1);
        }
        default: /*parent*/
        {
            i = 5;
            while (i-- > 0)
            {
                printf("parent process running\r\n");
                g_var++;
                var++;
                sleep(1);  /*仅仅调试用*/
            }
            printf("parent g_var:%d var:%d \r\n",g_var,var);
            exit(0);
        }
    }
}

2.2 创建守护进程

守护进程指的是没有和终端相连,后台运行,一般用于周期性执行某些任务。

 

#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>

/*@desp, 创建守护进程
*@return ,0 成功,-1 失败
*/
int daemon_init(void);

int main(void)
{
    time_t current;

    daemon_int();
    syslog(LOG_USER|LOG_INFO,"守护进程 \r\n");/*无终端,使用系统log*/

    while(1)
    {
        sleep(5);/*测试代码*/
        time(&current);
        syslog(LOG_USER|LOG_INFO,"守护进程-系统时间[\t%s\t\t] \n",ctime(&current));/*无终端,使用系统log*/
    }
}

int daemon_init(void)
{
    int pid;
    int i;

    signal(SIGTTOU,SIG_IGN); /*忽略终端OUT信号*/
    signal(SIGTTIN,SIG_IGN); /*忽略终端IN信号*/
    signal(SIGTSTP,SIG_IGN;  /*忽略stop信号*/
    signal(SIGHUP,SIG_IGN);  

    pid = fork();

    if (pid > 0)
    {
        exit(0);/*退出父进程*/
    }
    else if (pid < 0)
    {
        return -1; /*创建失败*/
    }
       
    setsid();/*新建进程组*/

    pid = fork();
    
    if (pid > 0)
    {
        exit(0);/*退出父进程*/
    }
    else if (pid < 0)
    {
        return -1; /*创建失败*/
    }

    for (i = 0;i < NOFILE;close(i++));/*关闭描述符*/

    chdir("/");/*设置根目录*/

    umask(0);/*设置屏蔽字*/

    signal(SIGCHLD,SIG_IGN);

    return 0;
}

2.3 退出进程

子进程 先于 父进程 终止,父进程调用wait等待,子进程进入僵死状态(耗费资源)

子进程 先于 父进程 终止,父进程调用wait等待,父进程等待子进程结束(推荐)

2.4 执行进程程序

使用exec 执行另一个可执行程序,代替当前进程的执行程序。

exec 本质是废弃原来的数据段 对战段,为新程序分配数据段和堆栈段,保留进程ID。

/*exec 家族函数*/
#include <unistd.h>

extern char **environ;

/*通过路径名,调用可执行文件*/
int execl(const char *path,const char *arg,...);
/*通过路径名,调用可执行文件*/
int execle(const char *path,const char *arg,...);
/*通过路径名,调用可执行文件*/
int execv(const char *path,char *const argv[]);

int execlp(const char *file,const char *arg,...);
int execvp(const char *file,char *const argv[]);
int execvpe(const char *file,char *const argv[],char *const evnp[]);
/*调用测试进程 test_process*/

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

int main(argc,char *argv[],char **env)
{
    pid_t pid;
    int   var_stat;

    pid = fork();

    if (pid == 0)/*child*/
    {
        printf("child process pid: %d parent pid:%d \r\n",getpid(),getppid());
        printf("child process uid: %d        gid:%d \r\n",getuid(),getgid());

        execve("test_process",argv,env);/*执行新的代码*/

        printf("never run here \n");
        exit(0);
        
    }
    else if (pid < 0)/*failed*/
    {
        perror("create process failed\r\n");
        exit(1);
    }
    else
    {
        printf("parent process\r\n");
    }

    wait(&var_stat);
    exit(0);
}

2.5 等待进程结束

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

/* @desp, 父进程暂停执行,直到子进程结束
*  @param,stat 状态信息
*  @return, 返回子进程pid
*/
pid_t wait(int *stat);

/* @desp, 等待特定子进程结束
*  @param,stat 状态信息
*  @param,options 状态信息
*  @return, 返回子进程pid
*/
pid_t witpid(pid_t pid,int *stat,int options)

2.6 进程id

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

/* @desp, 获取进程id
*  @return, 返回进程pid
*/
pid_t getpid(void);

/*进程具有root权限,则函数将实际用户Id,有效用户Id,设置为参数uid
* 进程不具有root权限,但uid=实际用户id,则只将有效用户Id设置为uid,不改变实际用户Id
* 若不满足,则返回-1
*/
/* @desp, 设置进程用户id
*  @param,uid 用户id
*  @return, 0返回成功,其他失败
*/
int setuid(uid_t uid);

/* @desp, 设置进程组id
*  @param,gid 组Id
*  @return, 0返回成功,其他失败
*/ 
int setgid(gid_t gid);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值