范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Linux系统进程管理

  (一)进程族系
  就如同人类的族系一样,系统中众多的进程也存在族系关系:由父进程创建子进程,子进程再创建子进程,从而构成一棵树形的进程族系图,如图2-9所示。图中结点代表进程。
  图2-9 进程创建的层次关系
  在开机时,首先引导操作系统,把它装入内存。之后生成第一个进程(在UNIX中称作0号进程),由它创建1号进程及其它核心进程;然后1号进程又为每个终端创建命令解释进程(shell进程);用户输入命令后又创建若干进程。这样便形成了一棵进程树。树的根结点(即第一个进程0#)是所有进程的祖先。上一层结点对应的进程是其直接相连的下一层结点对应进程的父进程,例如1#进程是P20,P21,P2n这些进程的父进程。
  (二)进程管理
  进程管理主要包括创建进程、终止进程、阻塞进程、唤醒进程和更换进程映像等。
  · 创建进程
  一个进程可以动态地创建新进程,前者称作 父进程 ,后者称作 子进程 。引发创建进程的事件通常是调度新的批作业、交互式用户登录、操作系统提供服务和现有进程派生新进程。
  创建新进程时要执行创建进程的系统调用(如UNIX/Linux系统中的fork),其主要操作过程有如下4步:
  (1)申请一个空闲的PCB。从系统的PCB表中找出一个空闲的PCB项,并指定惟一的进程标识号PID(即进程内部名)。
  (2)为新进程分配资源。根据调用者提供的所需内存的大小,为新进程分配必要的内存空间,存放其程序和数据及工作区。
  (3)将新进程的PCB初始化。根据调用者提供的参数,将新进程的PCB初始化。这些参数包括新进程名(外部标识符)、父进程标识符、处理机初始状态、进程优先级、本进程开始地址等。一般将新进程状态设置为就绪状态。
  (4)将新进程加到就绪队列中。一个进程派生新进程后,有两种可能的执行方式:
  ① 异步方式。即:父、子进程分道扬镳——父进程继续运行,子进程也可以被调度运行。
  ② 同步方式。即:父进程睡眠,等待它的某个或全部子进程终止,然后再继续运行。
  建立子进程的地址空间也有两种可能的方式:
  ① 子进程复制父进程的地址空间;
  ② 把新的程序装入子进程的地址空间。
  不同的操作系统采用不同的实现方式来创建进程。例如在UNIX系统中,每个进程有惟一的进程标识号(即PID),父进程利用fork系统调用创建新进程。父进程创建子进程时,把自己的地址空间制作一个副本,其中包括user结构、正文段、数据段、用户栈和系统栈。这种机制使得父进程很容易与子进程通信。两个进程都可以继续执行fork系统调用之后的指令,但有一个差别:fork的返回值(即子进程的PID)不等于0时,表示父进程在执行;而返回值等于0时,表示子进程在执行。Linux系统中也采用这种方式。
  · 终止进程
  当一个进程完成自己的任务后要终止自己,这是正常终止。如果进程在运行期间由于出现某些错误和故障而被迫终止,这是非正常终止。也可应外界的请求(如父进程请求)而终止进程。
  一旦系统中出现要求终止进程的事件后,便调用进程终止原语(原语是其操作不可分割的一段系统程序)。终止进程的主要操作过程是:
  (1)从系统的PCB表中找到指定进程的PCB。若它正处于运行态,则立即终止该进程的运行。
  (2)回收该进程所占用的全部资源。
  (3)若该进程还有子孙进程,则还要终止其所有子孙进程,回收它们所占用的全部资源。
  (4)释放被终止进程的PCB,并从原来队列中摘走。
  · 阻塞进程
  正在运行的进程因提出的服务请求未被操作系统立即满足,或者所需数据尚未到达等原因,只能转变为阻塞态,等待相应事件出现后再把它唤醒。
  正在运行的进程通过调用阻塞原语(如UNIX / Linux系统的sleep),主动地把自己阻塞。进程阻塞的过程如下:
  (1)立即停止当前进程的执行;
  (2)将现行进程的CPU现场送到该进程的PCB现场保护区中保存起来,以便将来重新运行时恢复此时的现场;
  (3)把该进程PCB中的现行状态由"运行"改为阻塞,把它插入到具有相同事件的阻塞队列中。
  (4)然后转到进程调度程序,重新从就绪队列中挑选一个合适进程投入运行。
  · 唤醒进程
  当阻塞进程所等待的事件出现时(如所需数据已到达,或者等待的I/O操作已经完成),则由另外的、与阻塞进程相关的进程(如完成I/O操作的进程)调用唤醒原语(如UNIX /Linux系统的wakeup),将等待该事件的进程唤醒。可见,阻塞进程不能唤醒自己。
  唤醒原语执行过程是:
  (1)首先把被阻塞进程从相应的阻塞队列中摘下;
  (2)将现行状态改为就绪态,然后把该进程插入到就绪队列中;
  (3)如果被唤醒进程比正在运行进程有更高的优先级,则设置重新调度标志。
  阻塞原语与唤醒原语恰好是一对相反的原语:调用前者是自己去睡眠,调用后者是把"别人"唤醒。使用时也要成对,前边有睡的,后边要有叫醒的。否则,前者就要"长眠"了。
  · 进程映像的更换
  子进程被创建之后,通常处于"就绪态"。以后,被进程调度程序选中才可以运行,即取得CPU的控制权。在有些系统(如UNIX/Linux)中,由于创建子进程时是把父进程的映像复制给子进程,所以父子进程的映像基本相同。如果子进程不改变自己的映像,就必然重复父进程的过程,这不是我们所要求的。为此,要改变子进程的映像,使它执行自己的特定程序。
  改变进程映像的工作很复杂,其主要过程是:
  (1)释放子进程原来的程序和数据所占用的内存空间;
  (2)从磁盘上找出子进程所要执行的程序和数据(通常以可执行文件的形式存放);
  (3)分配内存空间,装入新的程序和数据;
  (4)为子进程建立初始的运行环境——主要是对各个寄存器初始化,返回到用户态,运行该进程的程序。
  应当指出,以上几个进程管理原语是基本的功能性描述。在不同的操作系统中有不同的实现方式。
  (三)Linux进程管理
  1.Linux进程状态
  在Linux系统中,进程有下述5种状态:
  (1)运行态(TASK_RUNNING)。此时,进程正在运行(即系统的当前进程)或准备运行(即就绪态)。当前进程由运行指针所指向。
  (2)可中断等待态(TASK_INTERRUPTIBLE)。此时进程在"浅度"睡眠——等待一个事件的发生或某种系统资源,它能够被信号或中断唤醒。当所等待的资源得到满足时,它也被唤醒。
  (3)不可中断等待态(TASK_UNINTERRUPTIBLE)。进程处于"深度"睡眠的等待队列中,不能被信号或中断唤醒,只有所等待的资源得到满足时,才能被唤醒。
  (4)停止态(TASK_STOPPED)。通常由于接收一个信号,致使进程停止。正在被调试的进程可能处于停止态。
  (5)僵死态(TASK_ZOMBIE)。由于某些原因,进程被终止了,但是该进程的控制结构task_struct仍然保留着。
  如图2-10所示是Linux进程状态的变化。
  图2-10 Linux进程状态的变化
  2.进程的模式和类型
  在Linux系统中,进程的执行模式划分为用户模式(用户态)和内核模式(核心态)。如果当前运行的是用户程序、应用程序或者内核之外的系统程序,那么对应进程就在用户模式下运行;如果在用户程序执行过程中出现系统调用或者发生中断事件,就要运行操作系统(即核心)程序,进程模式就变成内核模式。在内核模式下运行的进程可以执行机器的特权指令,并且该进程不受用户的干预,即使是root用户也不能干预内核模式下进程的运行。
  按照进程的功能和运行的程序来分,进程划分为两大类:一类是系统进程,只运行在内核模式,执行操作系统代码,完成一些管理性的工作,如内存分配和进程切换。另一类是用户进程,通常在用户模式中执行,并通过系统调用或在出现中断、异常时进入内核模式。
  用户进程既可以在用户模式下运行,也可以在内核模式下运行,如图2-11所示。
  图2-11 用户进程的两种运行模式
  3.Linux进程结构
  · task_struct结构
  Linux系统中的每个进程都有一个名为task_struct的数据结构,它相当于"进程控制块"。系统中有一个进程向量数组task,该数组的长度默认值是512B,该数组的元素是指向task_struct结构的指针。在创建新进程时,Linux就从系统内存中分配一个task_struct结构,并把它的首地址 加入task数组。当前正在运行的进程的task_struct结构用current指针指示。
  task_struct结构包含下列信息:
  (1)进程状态。
  (2)调度信息。调度算法利用这个信息来决定系统中的哪一个进程需要执行。
  (3)标识符。系统中每个进程都有唯一的一个进程标识符(PID)。PID并不是指向进程向量的索引,仅仅是一个数字而已。每个进程还包括用户标识符(UID)和用户组标识符(GID),用来确定进程对系统中文件和设备的存取权限。
  (4)内部进程通信。Linux系统支持信号、管道、信号量等内部进程通信机制。
  (5)链接信息。在Linux系统中,每个进程都与其他进程存在联系。除初始化进程外,每个进程都有父进程。该链接信息包括指向父进程、兄弟进程和子进程的指针。
  (6)时间和计时器。内核要记录进程的创建时间和进程运行所用的CPU时间。Linux系统支持进程的时间间隔计时器。
  (7)文件系统。进程在运行时可以打开和关闭文件。task_struct结构中包括指向每个打开文件的文件描述符的指针,并且包括两个指向VFS(虚拟文件系统)索引节点的指针。第一个索引节点是进程的根目录,第二个节点是当前的工作目录。两个VFS索引节点都有一个计数字段,该计数字段记录访问该节点的进程数。
  (8)虚拟内存。大多数进程都使用虚拟内存空间。Linux系统必须了解如何将虚拟内存映射到系统的物理内存。
  (9)处理器信息。每个进程运行时都要使用处理器的寄存器及堆栈(参见下文关于堆栈的讲解)等资源。当一个进程挂起时,所有有关处理器的内容都要保存到进程的task_struct中。当进程恢复运行时,所有保存的内容再装回到处理器中。
  · 进程系统堆栈
  在Linux系统中,每个进程都有一个系统堆栈,用来保存中断现场信息和进程进入内核模式后执行子程序(函数)嵌套调用的返回现场信息。每个进程的系统堆栈和task_struct数据结构之间存在紧密联系,因而二者物理存储空间也连在一起,如图2-12所示。
  图2-12 进程的系统堆栈和task_struct结构
  由图2-12中可以看出,内核在为每个进程分配task_struct结构的内存空间时,实际上是一次分配两个连续的内存页面(共8KB),其底部约1KB的空间用于存放task_struct结构,而上面的约7KB的空间用于存放进程系统堆栈。
  另外,系统空间堆栈的大小是静态确定的,而用户空间堆栈可以在运行时动态扩展。
  (四)对进程的操作命令
  在Linux中,通常执行任何一个命令都会创建一个或多个进程,即命令是通过进程实现的。当进程完成了预期的目标,自行终止时,该命令也就执行完了。不但用户可以创建进程,系统程序也可以创建进程。可以说,一个运行着的操作系统就是由许许多多的进程组成的。
  1.ps命令
  ps命令是查看进程状态的最常用的命令,它可以提供关于进程的许多信息。操作者可以根据显示的信息确定哪个进程正在运行,哪个进程是被挂起或出了问题,进程已运行了多久,进程正在使用的资源情况,进程的相对优先级以及进程的标识号(PID)。所有这些信息对用户都很有用,对于系统管理员来说更为重要。
  ps命令的一般格式是:  ps [选项]
  例如,不带选项的ps命令可以列出每个与当前shell有关的进程的基本信息:
  $ ps
  PID
  TTY
  TIME
  CMD
  1788
  pts/1   00:00:00   bash   1822
  pts/1   00:00:00   ps   其中,各字段的含义如下:   PID 进程标识号。   TTY 该进程建立时所对应的终端,"?"表示该进程不占用终端。   TIME 报告进程累计使用的CPU时间。注意,尽管有些命令(如sh)已经运转了很长时间,但是它们真正使用CPU的时间往往很短。所以,该字段的值往往是00:00:00。   CMD 执行进程的命令名,command的缩写。   Ps命令的常用选项有:   -a 显示系统中与tty相关的(除会话组长之外)所有进程的信息。   -e 显示所有进程的信息。   -f 显示进程的所有信息。   -l 以长格式显示进程信息。   -r 只显示正在运行的进程。   -u 显示面向用户的格式(包括用户名,CPU及内存使用情况、进程运行状态等信息)。   -x 显示所有终端上的进程信息。 例如,下面的命令行可以显示系统中所有进程的全面信息:   $ ps -ef   UID   PID   PPID   C   STIME   TTY   TIME   CMD   root   1
  0
  1
  20:42   ?   00:00:05   init [5]   root   2
  1
  0
  20:42   ?   00:00:00   [keventd]   root   3
  1
  0
  20:42   ?   00:00:00   [ksoftirqd_CPU0]   ……   mengqc   1823
  1788
  0
  21:39   pts/1   00:00:00   ps -ef   各项的含义是(只标出与前例不同的部分,其余含义相同):   UID 进程属主的用户ID号。   PPID 父进程的ID号。   C 进程最近使用CPU的估算。   STIME 进程开始时间,以"小时:分:秒"的形式给出。   2.kill命令   信号(signal,也称作软中断)机制是在软件层次上对中断机制的一种模拟。异步进程可以通过彼此发送信号来实现简单通信。系统预先规定若干个不同类型的信号(如x86平台中Linux内核设置了32种信号,而现在的Linux和POSIX.4定义了64种信号),各表示发生了不同的事件,每个信号对应一个编号。进程遇到相应事件或者出现特定要求时(如进程终止或运行中出现某些错误——非法指令和地址越界等),就把一个信号写到相应进程task_struct结构的signal位图(表示信号的整数)中。接收信号的进程在运行过程中要检测自身是否收到了信号,如果已收到信号,则转去执行预先规定好的信号处理程序。在处理之后,再返回原先正在执行的进程。   kill命令是通过向指定进程发送指定的信号来终止相应进程。终止一个前台进程可以使用键,也可以使用kill命令。但是,对于一个后台进程就只能用kill命令来终止。   kill命令的一般格式是:   kill [-s 信号|-p ] 进程号…   kill -l [信号]   其中,各选项的含义如下:   -s 指定要发送的信号——可以是信号名(如SIGKILL),也可以是对应信号的编号(如9)。   -p 指定kill命令只是显示进程的PID(进程标识号),并不真正发出终止进程的信号。   -l 显示信号名称列表,这也可以在/usr/include/linux/signal.h文件中找到。   使用kill命令时应注意:   (1)kill命令可以带信号,也可以不带。如果没有带信号,kill命令就会发出终止信号(编号为15),这个信号可以被进程捕获,使得进程在退出之前清理并释放资源。也可以用kill向进程发送特定的信号,例如:kill -2 123 。它的效果等同于:当在前台运行PID为123的进程时,按下键。但是,普通用户使用kill命令时不要带信号,或者至多带信号编号9。   (2)kill可以用进程ID号作为参数。当用kill向这些进程发送信号时,必须是这些进程的主人。如果试图撤销一个没有权限撤销的进程或撤销一个不存在的进程,就会得到一个错误信息。   (3)可以向多个进程发信号或终止它们。   (4)当kill成功地发送了信号后,shell会在屏幕上显示出进程的终止信息。有时这个信息不会马上显示,只有当按下键使shell的命令提示符再次出现时,才会显示出来。   (5)应注意,信号使进程强行终止,这常会带来一些副作用,如数据丢失或者终端无法恢复到正常状态。发送信号时必须小心,只有在万不得已时,才用SIGKILL信号(编号为9),因为进程不能首先捕获它。   要撤销所有的后台作业,可以输入kill 0。因为有些在后台运行的命令会启动多个进程,跟踪并找到所有要杀掉的进程的PID是件很麻烦的事。这时,使用kill 0 来终止所有由当前shell启动的进程,是个有效的方法。   一般可以用kill命令来终止一个已经挂起的进程或者一个陷入死循环的进程。例如:首先执行以下命令,人为建立一个好像陷入死循环的后台进程:   $ find / -name core -print > /dev/null 2>&1&   这是一条后台命令,执行时间较长。其功能是:从根目录开始搜索名为core的文件,将结果输出(包括错误输出)都定向到 /dev/null文件。   现在决定终止该进程。为此,运行ps命令来查看该进程对应的PID。例如,该进程对应的PID是1651,现在用kill命令"杀死"这个进程:   $ kill 1651   再用ps命令查看进程状态时,就可以看到,find进程已经不存在了。   3.sleep命令   sleep命令的功能是使进程暂停执行一段时间。其一般使用格式是:   sleep 时间值   其中,"时间值"参数以秒为单位,即让进程暂停由时间值所指定的秒数。此命令大多用于shell程序设计中,使两条命令执行之间停顿指定的时间。   例如,下面的命令使进程先暂停100秒,然后查看用户mengqc是否在系统中:   $ sleep 100; who | grep "mengqc"   (五)有关进程控制的系统调用   1.系统调用的使用方式   虽然在一般应用程序的编制过程中,利用系统提供的库函数就能很好地解决问题,但在处理系统底层开发、进程管理等方面的涉及系统内部操作的问题时,利用系统调用编程就很必要,而且程序执行的效率会得到改进。   在UNIX/Linux系统中,系统调用和库函数都是以C函数的形式提供给用户的,它有类型、名称和参数,并且要标明相应的文件包含。例如,open系统调用可以打开一个指定文件,其函数原型说明如下:   #include   #include   #include   int open(const char *path, int oflags);   不同的系统调用所需要的头文件(又称前导文件)是不同的。这些头文件中包含了相应程序代码中用到的宏定义、类型定义、全称变量及函数说明等。对C语言来说,这些头文件几乎总是保存在/usr/include及其子目录中。系统调用依赖于所运行的UNIX/Linux操作系统的特定版本,所用到的头文件一般放在/usr/include/sys或者 /usr/include/linux目录中。   在C语言程序中,对系统调用的调用方式与调用库函数的方式相同,即:调用时提供的实参的个数、出现的顺序和实参的类型应与原型说明中形参表的设计相同。例如,要打开在目录/home/mengqc下面的普通文件myfile1,访问该文件的模式为可读可写(用符号常量O_RDWR表示),则代码片段为:   int fd;   …   fd=open("/home/mengqc/myfile1",O_RDWR);   …   虽然从感觉上系统调用类似于库函数调用:都由程序代码构成,使用方式相同——调用时传送参数。但两者有实质差别:库函数属于用户层,它只能在用户态下运行,不能进入核心态;而系统调用属于操作系统核心层,在核心态下运行,并且可以实现处理机从用户态到核心态的转变。   2.有关进程控制的系统调用   常用的有关进程控制的系统调用有:fork,exec,wait,exit,getpid,sleep和nice等。查看表2-1列出了这些系统调用的格式和功能说明 。   表2-1 有关进程控制的系统调用的格式和功能说明   格式   功能   #include   #include   pid_t fork(void);   创建一个子进程。pid_t表示有符号整型量。若执行成功,在父进程中,返回子进程的PID(进程标识符,为正值);在子进程中,返回0。若出错,则返回 1,且没有创建子进程   #include   #include   pid_t getpid(void);   pid_t getppid(void);   getpid返回当前进程的PID,而getppid返回父进程的PID   #include   int execve(const char *path,char *const argv[],char *const envp[]);   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[]);   这些函数被称为"exec函数系列",其实并不存在名为exec的函数。只有execve是真正意义上的系统调用,其他都是在此基础上经过包装的库函数。该函数系列的作用是更换进程映像,即根据指定的文件名找到可执行文件,并用它来取代调用进程的内容。换句话说,即在调用进程内部执行一个可执行文件。其中,参数path是被执行程序的完整路径名;argv和envp分别是传给被执行程序的命令行参数和环境变量;file可以简单到仅仅是一个文件名,由相应函数自动到环境变量PATH给定的目录中去寻找;arg表示argv数组中的单个元素,即命令行中的单个参数   #include   void _exit(int status);   #include   void exit(int status);   终止调用的程序(用于程序运行出错)。参数status表示进程退出状态(又称退出值、返回码、返回值等),它传递给系统,用于父进程恢复。_exit函数比exit函数简单些,前者使得进程立即终止;后者在进程退出之前,要检查文件的打开情况,执行清理I/O缓冲的工作   #include   #include   pid_t wait(int *status);   pid_t waitpid(pid_t pid, int *status,int option);wait( )等待任何要僵死的子进程;有关子进程退出时的一些状态保存在参数status中。如成功,返回该终止进程的PID;否则,返回1   而waitpid( )等待由参数pid指定的子进程退出。参数option规定了该调用的行为:WNOHANG表示如没有子进程退出,则立即返回0;WUNTRACED表示返回一个已经停止但尚未退出的子进程的信息。可以对它们执行逻辑"或"   #include   unsigned int sleep(unsigned int seconds);   使进程挂起指定的时间,直至指定时间(由seconds表示)用完或者收到信号   #include   int nice(int inc);   改变进程的优先级。普通用户调用nice时,只能增加进程的优先数(inc为正值);只有超级用户才能减少进程的优先数(inc为负数)。如成功,返回0;否则,返回1   3.应用示例   【例2-1】子进程被创建后,一般会使用一个exec函数来更换自己的映像,即用一个程序(如可执行文件)取代原来内存空间中的内容,然后开始执行。此后,父、子进程就各行其道了。父进程可以创建多个子进程。当子进程运行时,如果父进程无事可做,就执行wait系统调用,把自己插入睡眠队列中,等待子进程的终止。   下面这个C程序展示了Linux系统中父进程创建子进程以及各自分开活动的情况。   【例2-2】每个进程都有唯一的进程ID号(PID)。PID通常在数值上逐渐增大,因此,子进程的PID一般要比其父进程大。当然,PID的值不可能无限大,当它超过系统规定的最大值时,就反转回来使用最小的尚未使用的PID值。   如图2-9所示,进程族系呈树型结构。除0#外,任何进程都必须有父进程,不允许出现"孤儿"进程。如果父进程先于子进程死亡或退出,则子进程会被指定一个新的父进程init(其PID为1)。   下面的程序利用fork( )创建子进程,利用getpid( )和getppid( )分别获得本进程的PID和父进程的PID,使用sleep( )将相关进程挂起几秒钟。本程序的可执行文件名为proc1。   /*proc1.c演示有关进程操作*/   #include   #include   #include   #include   int main(int argc,char **argv)   {   pid_t pid,old_ppid,new_ppid;   pid_t child,parent;   parent=getpid(); /*获得本进程的PID*/   if((child=fork())<0){ /*如果新创建子进程的PID小于0*/   fprintf(stderr,"%s:fork of child failed:%s ",argv[0],strerror(errno)); /*输出创建子进程失败*/   exit(1); /*终止,返回码为1*/   }   else if(child==0){ /*此时是子进程被调度运行*/   old_ppid=getppid(); /*取得父进程的PID*/   sleep(2); /*睡眠2秒钟,以便调度其他进程运行*/   new_ppid=getppid(); /*当再次被调度运行后,取得新父进程的PID*/   }   else { /*父进程运行*/   sleep(1); /*睡眠1秒钟,以便调度其他进程运行*/   exit(0); /*被调度运行时,父进程终止*/   }   /*下面仅子进程运行*/   printf("Original parent:%d ",parent); /*输出最初父进程的PID*/   printf("Child:%d ",getpid()); /*取得并输出子进程的PID*/   printf("Child"s old ppid:%d ",old_ppid); /*输出父进程的PID*/   printf("Child"s new ppid:%d ",new_ppid); /*输出新父进程的PID*/   exit(0); /*程序终止*/   }   程序运行的结果如下:   $ ./proc1   $ Original parent:2009   Child:2010   Child"s old ppid:2009   Child"s new ppid:1   请读者根据输出结果自行分析程序的执行情况。注意,进程是并发执行的;当子进程被成功调度后,调度程序的返回值是0。如果父进程先终止,则其子进程的父进程就被系统指定为init进程(其PID为1)。

孩子惊厥会不会引起抽动症?抽动症的这些诱因,许多家长都不知道孩子惊厥是一种常见的急性疾病,通常发生在5岁以下的儿童身上。当孩子突然昏迷呼吸困难全身僵硬甚至发生痉挛时,家长们常常会感到十分害怕和不知所措。其中,引起家长担忧的抽动症状是很常见的辛巴不断优化辛选供应链体系,助力直播电商行业快速发展在当今数字化和智能化的时代,供应链已经成为企业的核心竞争力之一,对于直播电商行业而言更是至关重要。辛选集团的创始人辛巴凭借其敏锐的商业头脑和对供应链的深刻理解,成功地将辛选供应链体新港区抢滩新风口新赛道,推动新型储能材料项目加速4月3日,城陵矶新港区党工委书记李建华赴临港高新产业园调研新型储能材料产业项目。红网时刻岳阳4月4日讯(通讯员何中帅)4月3日,城陵矶新港区党工委书记李建华赴临港高新产业园调研新型孩子近视度数一直狂飙?可能是你没选对眼镜!这3点家长必看!十三岁之前,是孩子视觉视力发育的重要阶段和时期。家长发现孩子视力下降后,一定要带孩子去医院做散瞳验光检查,通过检查,明确是真性近视后,那么就要采取治疗措施。很多家长就会问,孩子近视郭家桥学区陈家铺镇中心幼儿园开展清明节主题活动清明节既是中华民族的传统节日,也是反映自然界物候变化的重要节气。郭家桥学区陈家铺镇中心幼儿园组织开展了形式多样的清明节主题活动,引导幼儿传承和弘扬中华民族优秀传统文化和民族精神。话有声绘本全都是我的!教会孩子控制自己的占有欲乐爸导读今天分享的绘本故事叫全都是我的!,故事讲述了花袜子每每看到朋友的玩具,心里都痒痒的,他千方百计的守住得到的宝贝,拒绝朋友的邀请,整天趴在被窝里。朋友们玩的很开心,而花袜子只安抚奶嘴会影响牙齿发育?还会影响宝宝颜值?2023育儿季不少爸妈在哄孩子的时候都会使用安抚奶嘴,来安抚宝宝哭闹。可也有不少传言使用安抚奶嘴会造成乳头混乱,影响母乳喂养使用安抚奶嘴会影响孩子牙齿发育长期使用安抚奶嘴,就戒不掉家庭教育的症结,关键在哪里好内容我来评家长百问百答现今社会,教育是一个非常重要的话题,但人们更多地是关注到了学校教育存在的问题,而忽视了教育的另外一个方面家庭教育。家庭教育某种程度上是被忽视了重要性的话题,惠济这个幼儿园的万人运动会真会玩河南日报客户端记者曹萍迎着阳春四月的第一缕阳光,4月1日,惠济区实验幼儿园教育集团春季亲子运动会如约而至。一大早,从惠济区各处赶来的家长和孩子洋溢着笑脸陆续入场,不多会儿,郑州市第草莓新鲜上市的季节,怀孕能吃草莓吗?2023育儿季导读春天,很多市场上都有各种不同的草莓新鲜上市,相对于冬天时候居高不下的价格,春天的草莓就显得亲民了很多,所以也就进入了吃草莓的好季节。而草莓独特的香甜气息和清甜的口漫步无锡绿道,感受家门口的诗与远方来源交汇点新闻客户端交汇点讯绿道是亲近自然健身游憩最简单直接的途径,在植物塑造的空间中慢步骑行,体验无锡春日游杏花吹满头的浪漫,领略江南无所有,聊赠一枝春的热情,感受天街小雨润如酥
陕西白水郭永平原创忙趁春光踏青去忙趁春光踏青去阳春三月的白水大地充满生机与活力。如此美好的春光自然不容错过,迎着和煦的春风去踏青,去感受和享受大自然的美好。春的气息唤醒了沉睡一冬的大地。游走在城外旷野间满目的绿色12GB512GBIP68防水,从6999元跌至4999元,优秀旗舰价格大跳水小米自从十周年之后就宣布了要发布属于自己的高端旗舰机,放弃一味追求性价比而专攻高端旗舰方向的手机产品。而之前以为发烧而生的小米手机现在走上高端道路,他的手机性能是否能够满足消费者的假如给你三天时间,会选择去哪里玩?来留言吧假如给你三天时间游览一个地方,你会选择去哪里呢?欢迎大家留意,这里给大家推荐一个好地方。武陵源风景名胜区是我国第一个国家森林公园,它有四大景区组成张家界国家森林公园,天子山自然保护最美人间四月天,来楠溪江滩地和春天来个约会吧文图瓯江帆影胜日春光楠溪边,一片绿茵入眼来。东风戏童满滩跑,碧空鹞影乐开怀。江中长滩水迢迢,横木尽头鹭徘徊。苍暮三冠金辉洒,催熟帐下忘我菜。清茶浊酒何须急,千金春宵伴兄台。星光霓虹中国最美丽的海岛,碧海蓝天,美如画卷,看看你都去过几座中国有着丰富多彩的地质资源和地貌景观,在周边分布几千座大小的岛屿,以独特的魅力,因清净而美丽,因美丽而富饶,如我们所知中国的台湾岛与海南岛,还有美丽的西沙和南沙群岛,以及澎湖列岛,春日户外露营,北京这6处地方不能错过眼下正是露营的好时节周末不妨和家人朋友找一块绿地伴着春风支起一顶帐篷远离喧嚣,亲近大自然享受美好的休闲时光金海湖金海湖风景区位于平谷区城东15公里处,现为AAAA级景区,水域面积6世界真奇妙老挝送水节每年从六月到九月,是老挝的雨季,也是湄公河泛滥的季节。每当雨季,两岸的园田和房屋常被大水淹没。尽管如此,老挝人还是把湄公河看成圣河。当水退了之后,他们很快就搬回原地,选择日子举行一由沙进人退到绿进沙退敢把沙漠变绿洲(山水林田湖草沙系统治理故事)宁夏腾格里沙漠里扎起的草方格。新华社记者冯开华摄内蒙古库布其七星湖景区。新华社记者金良快摄陕西省榆林市米脂县银州街道高西沟村满眼绿色。新华社记者陶明摄阳春时节,东风过处,百草滋荣。君亭酒店狂奔成为旅企龙头股,五一黄金周有救了本文来自微信公众号空间秘探(IDMESPACE007),作者熊初墨。最近几天,君亭酒店股票突然成为各大旅游酒店群讨论最多的热议话题,4月12日,君亭酒店单日又上涨20,这是今年君亭漫游老挝六日(2)第二天领队在从广州出发时就一再提醒我们老挝在东南亚地区经济是最差的,所以吃住条件不能和国内以及其它地区比。可是从昨天的用餐以及入住酒店的条件看,感觉并不差。酒店房间宽敞干净,设施齐读走西藏列山古墓,藏东南最大的吐蕃墓群,气势恢宏杨辉麟游记列山古墓群,位于西藏林芝市朗县境内的东嘎乡列村东北约1。5公里的列山南坡。2000年被列为全国重点文物保护单位。海拔3200米。古墓群平面呈梯形,坐北朝南,封土堆高1。6