1-3节linux系统编程

进程创建和调度

1)进程

进程:程序的一次执行在操作系统中的影像
进程控制块(PCB):对于操作系统来说,PCB即代表整个进程
进程主要管理执行所需的资源
进程ID号:gepid/geppid
复制创建新进程:fork();
替换创建新进程:exec函数族
等待子进程的退出:wait/waitpid
进程的执行状态:新建,就绪,运行,阻塞,退出
僵尸进程:子进程退出之后,没有被父进程wait
孤儿进程:父进程在子进程之前退出,该子进程称为孤儿进程,进而被init进程收养
子进程ID: pid_t getpid
父进程ID: pid_t getppid

2)fork镜像创建新函数

fork()
#include <unistd.h>
pid_t fork(void);

2.1)字符串的分割

char *strtok(char *src, char *flag)
参数一是你要截取的字符串,参数2是字符串中的分隔符

3)exec族函数
 #include <unistd.h>

后缀:-l -v (NULL结尾) -p
参数例:

       extern char **environ;
       int execl(const char *path, const char *arg, ...);
       int execlp(const char *file, const char *arg, ...);
       int execle(const char *path, const char *arg,..., 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[]);
4)父子进程

pid_t fork();
父进程创建子进程
成功返回0
失败返回-1

父子进程 1.不保证先后顺序2.不保证打断多久3.原则上保证子进程先运行
父进程先于子进程退出,子进程被init进程(1号进程)收养

5)僵尸进程

子进程结束时, 父进程会收到这个SIGCHLD信号。如果父进程没有处理这个信号,也没有等待(wait)子进程,子进程虽然终止,但是还会在内核进程表中占有表项,这时的子进程称为 僵尸进程。

5.1)查看僵尸进程

在linux中,利用命令ps,可以看到有标记为Z的进程就是僵尸进程。
  ps -ef|grep defunc可以找出僵尸进程.
  可以用ps的-l选项,得到更详细的进程信息. F(Flag):一系列数字的和,表示进程的当前状态。这些数字的含义为:
  00:若单独显示,表示此进程已被终止。
  01:进程是核心进程的一部分,常驻于系统主存。如:sched、 vhand 、bdflush 等。
  02:Parent is tracing process.
  04:Tracing parent’s signal has stopped the process; the parent is waiting ( ptrace(S)).
  10:进程在优先级低于或等于25时,进入休眠状态,而且不能用信号唤醒,例如在等待一个inode被创建时   
  20:进程被装入主存(primary memory)
  40:进程被锁在主存,在事务完成前不能被置换
  S(state of the process )
  O:进程正在处理器运行 
  S:休眠状态(sleeping)
  R:等待运行(runable)   
  I:空闲状态(idle)
  Z:僵尸状态(zombie)   
  T:跟踪状态(Traced)
  B:进程正在等待更多的内存页
  C:cpu利用率的估算值(cpu usage)

5.2)僵尸进程清除的方法

1.改写父进程,在子进程死后要为它收尸
2.kill -18 PPID (PPID是其父进程)这个信号是告诉父进程,该子进程已经死亡了,请收回分配给他的资源。
3.终止父进程,要先看其父进程又无其他子进程,如果有,可能需要先kill其他子进程,也就是兄弟进程,kill –15 PID1 PID2 (PID1,PID2是僵尸进程的父进程的其它子进程)。

6)wait() and waitpid()

wait族函数头文件
#include <sys/types.h>
#include <sys/wait.h>

//参数
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
int  waitid(idtype_t  idtype,  id_t  id,  siginfo_t  *infop, int options);
//返回值
       The value of pid can be:
       < -1   meaning wait for any child process whose process group ID
              is equal to the absolute value of pid.
       -1     meaning wait for any child process.
       0      meaning wait for any child process whose process group ID
              is equal to that of the calling process.
       > 0    meaning  wait  for the child whose process ID is equal to
              the value of pid.

简单模拟shell脚本

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include <sys/wait.h>

#define MAX_TIPS_STR_LEN 500
#define MAX_CMD_LEN 128
#define DEBUG_MODE 1
#define MAX_PATH_LEN 200

int main (int argc ,char *argv[])
{
int status = 0;
pid_t pid;
//存储命令提示符字符串
char tips_string[MAX_TIPS_STR_LEN] = {'\0'};
//存储从键盘读取的命令字符串
char command[MAX_CMD_LEN]={'\0'};
//存储当前工作目录
while(1)
    {
        //1.print  tips 拼接命令提示符
        //printf("%s",getpwuid(getuid()) -> pw_name);
        //printf(">>**>>>");
        //printf("%s$",getcwd(cwd,MAX_PATH_LEN));
        //2.input command string form keyboard

        getcwd(cwd,MAX_PATH_LEN);
        sprintf(tips_string,"%S:%S$", getpwuid(getuid() ) ->pw_name, cwd);
        printf("%s",tips_string);
        //从键盘读取shell命令字符串,并去除'\n'
        fgets(command,MAX_CMD_LEN, stdin);
        //replace '\n'
        command [ strlen(command) -1 ] = '\0';
        //创建子进程执行读取的shell命令
        //3.create a new child process to run command
        if((pid = fork() ) == 0 )
        {
            //注意对带参数和选项的shell命令,需要对其进行划分
            printf("prepare %d\n",command);
                
            if(execlp(command, command, NULL) == -1 )
            {
            printf("input error\n");
            return 1;
            }
        }

    else if(pid >0) 
            {
        //2.wait for input command
        //等待子进程执行结束,并防止僵尸进程的产生
        wait(NULL);
            }
    }
return 0;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容