当前位置: 首页 > news >正文

微擎做的网站好排名吗腾讯的网络营销模式

微擎做的网站好排名吗,腾讯的网络营销模式,网页框架是什么,网站设置了权限目录 一、cwd的理解 二、fork的理解 1.代码共享 2.各司其职 3.fork的返回值 三、进程状态 1.进程排队 2.进程状态 运行状态 阻塞状态 挂起状态 一、cwd的理解 cwd(current working directory)。译为当前工作目录。 在C语言中,使用…

目录

一、cwd的理解

二、fork的理解

1.代码共享

2.各司其职

3.fork的返回值

三、进程状态

1.进程排队

2.进程状态

运行状态

阻塞状态

挂起状态


一、cwd的理解

        cwd(current working directory)。译为当前工作目录

        在C语言中,使用fopen函数打开文件时,第一个参数为当前目录下的某个文件的文件名,那么如何理解“当前目录”

        我们已经知道在/proc目录下,以文件的形式存放着每一个进程。

        需要注意的是,只有当一个可执行程序被执行后,对应的进程文件才会在/proc目录下出现。

[euto@VM-4-13-centos 24915]$ ./myprocess 
i am a process! id: 3800,fid: 2963 
i am a process! id: 3800,fid: 2963 
i am a process! id: 3800,fid: 2963 
i am a process! id: 3800,fid: 2963 
···········

        同时在/proc目录下,出现一个进程目录3800

[euto@VM-4-13-centos 24915]$ ls /proc
1      16     264    36    560   acpi         kallsyms      scsi
10     170    265    3647  562   buddyinfo    kcore         self
1005   17110  269    37    563   bus          keys          slabinfo
1071   18     27     3721  568   cgroups      key-users     softirqs
1074   1825   275    376   575   cmdline      kmsg          stat
1077   19     28     38    6     consoles     kpagecount    swaps
11     196    28150  3800  637   cpuinfo      kpageflags    sys
1100   2      285    4     638   crypto       loadavg       sysrq-trigger
1196   20     28704  400   639   devices      locks         sysvipc
12     21     28720  403   640   diskstats    mdstat        timer_list
1206   22     28721  407   641   dma          meminfo       timer_stats
1207   23     29     4452  65    driver       misc          tty
1218   23737  290    46    671   execdomains  modules       uptime
1219   24     291    48    7     fb           mounts        version
13     25     2959   49    8     filesystems  mtrr          vmallocinfo
1347   259    2962   50    9     fs           net           vmstat
1354   25995  2963   51    9648  interrupts   pagetypeinfo  xpmem
1373   26     30772  516   9684  iomem        partitions    zoneinfo
14     262    3123   5375  9802  ioports      sched_debug
14075  263    35     5421  9803  irq          schedstat

        我们可以查看进程3800的目录。

[euto@VM-4-13-centos 24915]$ ll /proc/3800 
total 0
dr-xr-xr-x 2 euto euto 0 Sep 18 10:20 attr
-rw-r--r-- 1 euto euto 0 Sep 18 10:20 autogroup
-r-------- 1 euto euto 0 Sep 18 10:20 auxv
-r--r--r-- 1 euto euto 0 Sep 18 10:20 cgroup
--w------- 1 euto euto 0 Sep 18 10:20 clear_refs
-r--r--r-- 1 euto euto 0 Sep 18 10:17 cmdline
-rw-r--r-- 1 euto euto 0 Sep 18 10:20 comm
-rw-r--r-- 1 euto euto 0 Sep 18 10:20 coredump_filter
-r--r--r-- 1 euto euto 0 Sep 18 10:20 cpuset
lrwxrwxrwx 1 euto euto 0 Sep 18 10:17 cwd -> /home/euto/linux/24915
-r-------- 1 euto euto 0 Sep 18 10:17 environ
lrwxrwxrwx 1 euto euto 0 Sep 18 10:17 exe -> /home/euto/linux/24915/myprocess
dr-x------ 2 euto euto 0 Sep 18 10:17 fd
dr-x------ 2 euto euto 0 Sep 18 10:20 fdinfo
-rw-r--r-- 1 euto euto 0 Sep 18 10:20 gid_map
-r-------- 1 euto euto 0 Sep 18 10:20 io
·······················

        需要注意两个信息,exe所指向的就是该进程对应的可执行程序所在目录

        这里还有一个信息就是cwd,不难总结出来,cwd和进程是深深绑定的,换句话说,我们平时说讲的“当前目录”,其实就是和进程绑定的cwd。因此,在C语言中使用fopen打开当前目录下某个文件的操作,其实就是可执行程序运行起来后,对应的进程中cwd所指目录下的某个文件。

        下面对这个结论作验证,通过执行指令chdir来演示,chdir的功能用来改变当前的工作目录。

CHDIR(2)                   Linux Programmer's Manual                  CHDIR(2)NAMEchdir, fchdir - change working directorySYNOPSIS#include <unistd.h>int chdir(const char *path);int fchdir(int fd);
······

        修改源文件为以下内容。

[euto@VM-4-13-centos 24915]$ cat myprocess.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{printf("当前进程pid:%d\n",getpid());printf("修改目录前\n");sleep(30);printf("修改目录后\n");chdir("/home/euto/");sleep(30);FILE* fp =  fopen("test.txt","w");fclose(fp);return 0;
}

        演示结果应该为:修改目录前,cwd为当前文件所在的目录24915。修改目录后,cwd更改为/home/euto,执行fopen打开文件test.txt时,由于test.txt文件并不存在,所以新建一个文件test.txt,新建文件所在的目录是/home/euto

[euto@VM-4-13-centos 24915]$ ./myprocess 
当前进程pid:16846
修改目录前
[euto@VM-4-13-centos 24915]$ ll /proc/16846
total 0
dr-xr-xr-x 2 euto euto 0 Sep 18 10:43 attr
-rw-r--r-- 1 euto euto 0 Sep 18 10:43 autogroup
-r-------- 1 euto euto 0 Sep 18 10:43 auxv
-r--r--r-- 1 euto euto 0 Sep 18 10:43 cgroup
--w------- 1 euto euto 0 Sep 18 10:43 clear_refs
-r--r--r-- 1 euto euto 0 Sep 18 10:43 cmdline
-rw-r--r-- 1 euto euto 0 Sep 18 10:43 comm
-rw-r--r-- 1 euto euto 0 Sep 18 10:43 coredump_filter
-r--r--r-- 1 euto euto 0 Sep 18 10:43 cpuset
lrwxrwxrwx 1 euto euto 0 Sep 18 10:43 cwd -> /home/euto/linux/24915
-r-------- 1 euto euto 0 Sep 18 10:43 environ
lrwxrwxrwx 1 euto euto 0 Sep 18 10:43 exe -> /home/euto/linux/24915/myprocess
dr-x------ 2 euto euto 0 Sep 18 10:43 fd
dr-x------ 2 euto euto 0 Sep 18 10:43 fdinfo
·······

        程序执行chdir修改目录后。

[euto@VM-4-13-centos 24915]$ ./myprocess 
当前进程pid:16846
修改目录前
修改目录后
[euto@VM-4-13-centos 24915]$ ll /proc/16846
total 0
dr-xr-xr-x 2 euto euto 0 Sep 18 10:43 attr
-rw-r--r-- 1 euto euto 0 Sep 18 10:43 autogroup
-r-------- 1 euto euto 0 Sep 18 10:43 auxv
-r--r--r-- 1 euto euto 0 Sep 18 10:43 cgroup
--w------- 1 euto euto 0 Sep 18 10:43 clear_refs
-r--r--r-- 1 euto euto 0 Sep 18 10:43 cmdline
-rw-r--r-- 1 euto euto 0 Sep 18 10:43 comm
-rw-r--r-- 1 euto euto 0 Sep 18 10:43 coredump_filter
-r--r--r-- 1 euto euto 0 Sep 18 10:43 cpuset
lrwxrwxrwx 1 euto euto 0 Sep 18 10:43 cwd -> /home/euto
-r-------- 1 euto euto 0 Sep 18 10:43 environ
lrwxrwxrwx 1 euto euto 0 Sep 18 10:43 exe -> /home/euto/linux/24915/myprocess
dr-x------ 2 euto euto 0 Sep 18 10:43 fd
········

        查看/home/euto目录,发现test.txt文件新建在了这个目录,和预期符合。

[euto@VM-4-13-centos 24915]$ ls /home/euto/
linux  test.txt

二、fork的理解

        运行man fork查看fork的相关介绍。

FORK(2)                                                             Linux Programmer's Manual                                                             FORK(2)NAMEfork - create a child processSYNOPSIS#include <unistd.h>pid_t fork(void);

        fork这个函数用来创建一个子进程。

        父进程和子进程的关系:一个父进程可以有多个子进程,而一个子进程的父进程是唯一的。


        fork的返回值介绍。

RETURN VALUEOn success, the PID of the child process is returned in the parent, 
and 0 is returned in the child.  On failure, -1 is returned in the  parent, 
no  child process is created, and errno is set appropriately.

        子进程创建失败,返回负数。

        子进程创建成功,给父进程返回子进程的pid,给子进程返回0。(pid都是大于0的整数) 


1.代码共享

  • 结论:使用fork创建子进程后,父进程和子进程共享代码。

        解释:

        在目录24918下编辑源文件myprocess.c的内容。

[euto@VM-4-13-centos 24918]$ cat myprocess.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{printf("fork之前:i am a process ,pid:%d,ppid:%d",getpid(),getppid());fork();printf("fork之后:i am a process ,pid:%d,ppid:%d",getpid(),getppid());return 0;
}

        运行结果显示。

[euto@VM-4-13-centos 24918]$ ./myprocess 
fork之前:i am a process ,pid:16709,ppid:6682
fork之后:i am a process ,pid:16709,ppid:6682//父进程
fork之后:i am a process ,pid:16710,ppid:16709//子进程

        第二句printf被打印了两次的原因是,父进程和子进程分别进行了打印。在执行fork这个函数后,子进程就已经在内存中存在了,子进程和父进程指向同一个可执行程序,在fork函数后需要执行的代码被父子进程共享

        其中,一条打印结果的ppid是另一条打印结果的pid,说明这是父子进程。

        关于子进程的PCB,大部分内容和父进程相同。

        关于共享的可执行程序,代码和数据都只有一份。


2.各司其职

  • 结论:一般而言,父进程和子进程完成的功能是不同的,源文件的代码只有一份,但是通过条件判断语句让父进程和子进程可以实现不同的功能

        解释:编辑源文件myprocess.c的内容如下。

int main()
{printf("fork之前i am a process,pid:%d ,ppid:%d\n",getpid(),getppid());sleep(5);printf("开始创建子进程\n");pid_t id = fork();if(id < 0){return 1;}else if(id == 0){//子进程while(1){printf("fork之后,我是子进程,pid:%d,ppid:%d,id:%d\n",getpid(),getppid(),id);sleep(1);}}else{//父进程while(1){printf("fork之后,我是父进程,pid:%d,ppid:%d,id:%d\n",getpid(),getppid(),id);sleep(1);}}return 0;
}

        运行结果如下。

[euto@VM-4-13-centos 24918]$ ./myprocess 
fork之前i am a process,pid:32557 ,ppid:30035
开始创建子进程
fork之后,我是父进程,pid:32557,ppid:30035,id:32570
fork之后,我是子进程,pid:32570,ppid:32557,id:0
fork之后,我是父进程,pid:32557,ppid:30035,id:32570
fork之后,我是子进程,pid:32570,ppid:32557,id:0
fork之后,我是父进程,pid:32557,ppid:30035,id:32570
fork之后,我是子进程,pid:32570,ppid:32557,id:0
fork之后,我是父进程,pid:32557,ppid:30035,id:32570
fork之后,我是子进程,pid:32570,ppid:32557,id:0
······

        程序运行成功后,父进程和子进程执行各自的代码,但是源文件的代码在内存中只有一份,数据也是只有一份。

        如果子进程在执行的过程中修改某一个变量,实际上并不是修改变量本来的内存空间,而是在修改之前,完成一个“写时拷贝”的操作,拷贝一份新的空间用来给子进程操作,父进程也是如此。


3.fork的返回值

  • 为什么fork返回时,给父进程返回子进程的pid,给子进程返回0?

        如果作为子进程,只需要调用getppid即可获取到父进程,因为父进程是唯一的;如果作为父进程,是没有办法直接获取到子进程的pid的,因为子进程不唯一,可以有多个。

  • fork给两个进程返回了不同的值,众所周知,函数不可能返回两个值,因此,可以判断,fork函数返回了两次,那么fork是如何返回两次的?

        我们假设这是fork函数的函数体。

        在return语句之前,fork处理创建子进程相关的操作,且执行return这一行代码之前,子进程就已经被创建出来并活跃在内存中return语句的本质就写入到不同的进程,可以看作是特殊的返回,执行两次return分别返回到不同的进程中

  • 源代码中的id是一个变量,为什么一个变量可以有两个值?

        操作系统在设计进程的时候,就保证了进程之间是彼此独立的,互相不影响。且利用了虚拟内存等其他技术,使得在Linux下,用一个变量表示了不同的内存空间


        编写一次创建多个进程的源程序,代码如下。

const int num = 10;
void worker()
{int cnt = 10;while(cnt){printf("child %d is running,cnt:%d\n",getpid(),cnt);--cnt;sleep(1);}
}
int main()
{for(int i =0;i < num; ++i){pid_t id = fork();if(id<0){break;}if(id == 0){worker();exit(0);}printf("父进程成功创建子进程,id:%d\n",id);sleep(1);}sleep(10);return 0;
}

三、进程状态

1.进程排队

  • 为什么存在进程排队这样的现象?

        进程出现了排队,一定是在等待某个资源,毕竟硬件资源有限

  • 进程不是一直在运行的。进程在CPU上,也不是一直在运行的。

        比如,当程序执行到scanf这一行的时候,程序在等待键盘的输入,即在等待硬件资源(也可能是软件资源),因此进程不是一直在运行的。

        在CPU上,由于时间片的设计,CPU也不是一直在运行同一个进程。

  • 进程=PCB + 可执行程序,所谓的进程排队是可执行程序在排队还是PCB在排队?

        排队一定是利用了队列这种数据结构,那么单位类型是可执行程序的话消耗将会巨大无比,因此涉及排队,都是利用队列对PCB作排队

  • 不难发现,一个task_struct,既要利用链表这种数据结构,又要利用队列这种数据结构,那么底层是怎么实现的呢,是存储两份数据吗?

        并不是下面这样的实现。

        而是在task_struct内部封装链表结点或者队列结点,因此一个task_struct可以被链入到多个数据结构中。

         那么,在已知listnode地址的情况下,如何操作task_struct其他数据呢,这就和偏移量有关。

2.进程状态

        进程的三种状态:运行,阻塞,挂起

  • 状态是什么

        本质上,就是task_struct中的一个整型变量。

struct task_struct
{int status;····
}

        用整型变量表示不同的状态就类似define定义

#define new 1
#define ready 2
#define running 3
#define block 4
·····
  • 设计状态这一个属性的意义。

        通过进程的状态来决定下一步进程要做的动作


运行状态

        一个CPU对应一个运行队列当进程在运行队列中排队时,即为运行状态

阻塞状态

        操作系统管理硬件,先是利用面向对象来定义结构体,再用数据结构组织管理,大致是下面这样。

//struct是面向对象思想
struct device
{设备名设备操作方法设备状态链表结点//链表结点是数据结构思想
}

        如果一个进程正在运行队列中被CPU执行,但是该程序内部如果有像scanf这样的函数,需要等待硬件资源的获取,那么操作系统会把这个进程从运行队列中弹出来,然后把PCB状态修改为阻塞状态。紧接着,由于每一个硬件设备都像CPU一样有着一个队列,用来排队需要提供资源的进程。

struct device
{设备名设备操作方法设备状态链表结点等待队列的结点
}

        比如scanf需要键盘的资源,那么这个进程的PCB就会被链入到键盘的等待队列,这种状态就是阻塞状态

        当进程获取到资源后,操作系统作为硬件的管理者,捕获到这一讯息,再将PCB的阻塞状态修改为运行状态,链入到CPU的运行队列。

        也可以总结出来,所谓的PCB状态发生变化,本质就是PCB被链入到不同的队列

挂起状态

        进程变成挂起状态的情况相对较少

        挂起状态有一个前提,当计算机的软硬件资源有限的时候,进程可能变为挂起状态

        比如,某一个进程正在键盘中阻塞,但是内存或者其他设备的资源同时十分有限,计算机已经十分卡顿,如果继续让这个进程占用资源,可能引起操作系统的崩溃,因此,操作系统把这个进程相关的指令、数据(注意PCB不会被写入到硬盘),暂时写入到硬盘中,变成暂时挂起的状态。

         PCB由阻塞状态变成的挂起状态,称为阻塞挂起。

        磁盘上专门有一个分区,用来在内存资源有限的时候,进行数据、代码的写入写出操作,这个分区就是swap分区,swap分区一般是内存大小的一半,最好不要超过内存大小的两倍。

  • 从另一个角度理解挂起时PCB不会被写入到磁盘:我们知道进程 = PCB + 加载到内存中的可执行程序。那么,进程在被创建之前,是先创建PCB还是先把可执行程序加载到内存?

        答案是先创建PCB。操作系统用PCB管理程序,而有些大型游戏的可执行程序大小多达80GB,内存只有16GB大小,不可能全部加载到内存中,而是在创建完成PCB后,将部分数据加载到内存中,部分加载到swap分区,部分可能还在磁盘中,没有被调度到,但是操作系统仍然优秀地管理着这个可执行程序,原因就在于操作系统管理着PCB,而PCB就包含着一切信息。

http://www.yayakq.cn/news/419825/

相关文章:

  • 按键精灵官方网站怎么做脚本东门网站建设
  • 洛阳市政建设网站微信小程序如何申请
  • 聊城市公司网站建站开发公司如何编写意向书
  • 怎样建设游戏网站WordPress编辑文章空白
  • 手机商城网站设计要求怎么写做网站的好处在哪里
  • 做网站怎么招广告wordpress不能编辑文章
  • 做网站的图哪来个人怎么做一个网站
  • 苏州建设招投标网站住房和城乡建设局职责范围
  • 织梦php网站模板修改百度推广让我先做虚拟网站后
  • 洛阳市住房和城乡建设网站网页设计图片怎么居中
  • 东明县住房和城乡建设局网站常设中国建设工程法律网站
  • 信和财富网站开发郑州市建设工程信息网站
  • 表格网站怎么做三网合一网站
  • 网站续费合同书镇江网红景点
  • 杭州餐饮团购网站建设广州网站优化哪家快
  • 影视传媒广告公司网站模板设计好的制作网站
  • 温州市建设工程质量监督站网站网页文字模板
  • 在线做logo印章网站公司两个网站如何都备案
  • 福州高端网站制作武安建设局网站
  • 高州网站开发公司免费的seo教程
  • 申请建设门户网站的申请wordpress如何添加备案号代码
  • 内部购物券网站怎么做做网站定制
  • 网站做国际化12个优秀平面设计素材网站
  • 开公司网站创建费用wordpress 输入框
  • 婚纱网站设计素材p2p网贷网站建设公司
  • 做局域网网站教程桂林漓江在哪个位置
  • 抄袭网站案例金融公司网站源码
  • 广东建设执业资格注册管理中心网站网站 维护 费用
  • 怎样用腾讯云做网站自适应网站怎么做
  • app网站开发培训wordpress内容主题模板下载