重庆建设工程安全协会网站,蘑菇街网站怎么做,wordpress探针,郑州app软件公司文章目录一、终端概念终端概念控制终端二、进程组概念进程组概述进程组相关 API会话会话概念会话相关 API创建会话注意事项守护进程守护进程介绍守护进程模型守护进程参考代码守护进程相关 API参考文章一、终端概念
终端概念
1、终端#xff08;Terminal#xff09;
终端是…
文章目录一、终端概念终端概念控制终端二、进程组概念进程组概述进程组相关 API会话会话概念会话相关 API创建会话注意事项守护进程守护进程介绍守护进程模型守护进程参考代码守护进程相关 API参考文章一、终端概念
终端概念
1、终端Terminal
终端是物理设备只用于输入输出本身没有强大的计算能力。在计算资源紧张的时代人们想共享一台计算机可以通过终端连接到计算机上将指令输入终端终端传送给计算机计算机完成指令后将输出传送给终端终端将结果显示给用户所以有显示器和键盘能够通过串口连接到计算机的设备就叫终端。
2、控制台Console
控制台也是物理设备也用于输入输出但它直接连接在计算机上是计算机系统的一部分所以直接连接在电脑上的键盘和显示器就叫做控制台。计算机启动的时候所有的信息都会显示到控制台上而不会显示到终端上。简单的说能直接显示系统消息的那个终端称为控制台其他的则称为终端。
3、控制台与终端的区别
终端是通过串口连接上的不是计算机本身就有的设备而控制台是计算机本身就有的设备一个计算机只有一个控制台。也就是说控制台是计算机的基本设备而终端是附加设备。
简言之终端为主机提供了人机接口每个人都通过终端使用主机的资源。终端有字符终端和图形终端两种。一台主机可以连很多终端。 控制台是一种特殊的人机接口控制台也是终端的一种, 是人控制主机的第一人机接口而主机对于控制台的信任度高于其他终端。
4、TTY
TTY 是 Teletype 或 Teletypewriter 的缩写原来是指电传打字机后来这种设备逐渐键盘和显示器取代。不管是电传打字机还是键盘显示器都是作为计算机的终端设备存在的所以 TTY 也泛指计算机的终端设备。
5、虚拟控制台Virtual Console与虚拟终端Virtual Terminal
虚拟控制台和虚拟终端是一样的如果我们只有一台终端这是我们与计算机之间的用户接口假如有一天我们想拥有多个用户接口那么一方面我们可以增加终端数目另一方面还可以在同一台终端上虚拟出多个终端它们之间互相不影响至少看起来互相不影响。这些终端就是虚拟终端。Linux 默认所有虚拟终端都是控制台都能显示系统消息所以我们在平时的使用中压根就不区分 Linux 中的终端与控制台。
在 Ubuntu 桌面版中一共有七个虚拟终端tty1-7服务器版一般有六个虚拟终端tty1-6其中第七个虚拟终端是图形用户界面。我们可以使用 CTRLALTfn 切换虚拟终端例如 我们按下 CtrlAltF1 时会进入 tty1。
6、模拟终端器
如今终端不再是一个需要通过 UART 连接到计算机上物理设备。终端成为内核的一个模块它可以直接向 TTY 驱动发送字符并从 TTY 驱动读取响应然后打印到屏幕上。也就是说用内核模块模拟物理终端设备因此被称为终端模拟器所以终端是一种物理设备而终端模拟器是一个程序这些程序用来模拟物理终端。
7、shell
和之前说的几个概念截然不同之前的几个概念都是与计算机的输入输出相关的而shell是和内核相关的。内核为上层的应用提供了很多服务shell在内核的上层在应用程序的下层。例如你写了一个 hello world 程序你并不用显式地创建一个进程来运行你的程序你把写好的程序交给 shell 就行了由 shell 负责为你的程序创建进程。
我们在终端模拟器中输入命令时终端模拟器本身并不解释执行这些命令它只负责输入输出真正解释执行这些命令的是 shell。我们平时使用的 sh, bash, csh 是shell 的不实现。
控制终端
由于在 linux 中每一个系统与用户进行交流的界面称为终端每一个从此终端开始运行的进程都会依附于这个终端这个终端就称为这些进程的控制终端Controlling Terminal当控制终端被关闭时相应的进程都会自动关闭用户通过终端登录系统后得到一个 Shell 进程这个终端成为 Shell 进程的控制终端进程中控制终端是保存在 PCB 的信息中而 fork 会复制 PCB 中的信息因此由 Shell 进程启动的其它进程的控制终端也是这个终端。
默认情况下没有重定向每个进程的标准输入、标准输出和标准错误输出都指向控制终端进程从标准输入读也就是读用户的键盘输入进程往标准输出或标准错误输出写也就是输出到显示器上。
[[10_ Linux 进程通讯#四、进程间通讯之信号|信号]]一节中还讲过在控制终端输入一些特殊的控制键可以给前台进程发信号例如 CtrlC 表示 SIGINTCtrl\ 表示 SIGQUIT。
Linux 中所讲的终端除非特别说明否则一般都是指控制终端。 1tty 命令可以查看当前终端的名字。
yxm192:~$ tty
/dev/pts/12也可以通过函数查看终端的名字函数说明如下
#include unistd.h
char *ttyname(int fd);
功能由文件描述符查出对应的文件名
参数fd文件描述符
返回值成功终端名失败NULL下面我们借助 ttyname 函数通过实验看一下各种不同的终端所对应的设备文件名
#include stdio.h
#include unistd.h
int main() {printf(fd 0: %s\n, ttyname(0));printf(fd 1: %s\n, ttyname(1));printf(fd 2: %s\n, ttyname(2));return 0;
}yxm192:~$ gcc test.c -o test
yxm192:~$ ./test
fd 0: /dev/pts/0
fd 1: /dev/pts/0
fd 2: /dev/pts/03ps -aux 中 TTY 字段
TTY 字段显示的是 tty1-tty6 说明是在本地机器的命令行下登录的。 tty7 说明是在本地机器的图形界面下登录的TTY 字段显示的是 pts 说明是用远程工具连接的比如 xshell后面的数字代表登录的时间顺序越小证明登录的越早。
4一般情况下当前终端也是一个进程在当前终端开启的程序它的父进程一般也是当前终端。
二、进程组概念
进程组概述
进程组也称之为作业。BSD 于 1980 年前后向 Unix 中增加的一个新特性。代表一个或多个进程的集合。所以进行组由一个或多个共享同一进程组的进程组成。操作系统设计的进程组的概念是为了简化对多个进程的管理。
每个进程都属于一个进程组。当父进程创建子进程的时候默认子进程与父进程属于同一进程组。进程组 ID 为第一个进程的 ID进程组的第一个进程称为组长进程也叫首进程。所以对于组长进程标识而言其进程组 ID 为其本身进程 ID。进程组的标识符为 PGID
进程组拥有一个生命周期其开始时间为首进程创建组的时刻结束时间为最后一个成员进程离开终止或转移到另一个进程组组的时刻。一个进程可能会因为终止而退出进程组也可能会因为加入了另外一个进程组而退出进程组。进程组首进程无需是最后一个离开进程组的成员只要进程组中有一个进程存在进程组就存在与组长进程是否终止无关。
进程组的概念在 [[09_Linux 进程基础#4、进程回收|waitpid 函数]] 和 [[09_Linux 进程基础#2、进程控制命令|kill ]]中都曾使用到。例如可以使用 kill -SIGKILL -进程组ID 负的来将整个进程组内的进程全部杀死。
前台后台进程
Linux是一种用户控制的多作业操作系统 系统允许多个系统用户同时提交作业而一个系统用户可以用多个 shell 登录每个系统用户可以用一个 shell 提交多个作业。作业有两种运行方式前台运行和后台运行。
前台运行能够控制当前终端或窗口并且接受用户输入后台运行不在当前激活的终端或窗口中运行而是在用户“看不到”的情况下运行。 以前台运行方式运行的进程称作前台进程以后台运行方式运行的进程称作后台进程。
前台进程与后台进程特点如下
前台进程 在终端中启动运行的程序那么该终端就为进程的控制终端一旦这个终端关闭这个进程也随之消失。只有前台进程才能从控制终端中读取与输入。一般情况下前台进程的父进程是当前终端。使用 CTRLC 可以强行终止前台进程。 后台进程 后台进程与控制终端脱离【注意】后台程序并未完全脱离终端关闭当前终端也导致该后台进程退出此处与守护进程存在区别详细可以看下文“守护进程”一节内容。后台进程无法控制读取与输入后台进程并未完全脱离终端所以在终端未关闭前还是会往终端输出结果只是输出并不受控制终端控制具体表现是程序王终端输出结果同时终端还会出现命令提示符可以在终端输入命令。后台进程的父进程为系统进程1号进程使用 CTRLC 无法终止后台进程需要使用 kill -9 NNN 才能强行终止后台进程
进程组相关 API
一个进程可以为自己或子进程设置进程组 ID。
#include unistd.hpid_t getpgrp(void); /* POSIX.1 version */
功能获取当前进程的进程组ID
参数无
返回值总是返回调用者的进程组IDpid_t getpgid(pid_t pid);
功能获取指定进程的进程组ID
参数pid进程号如果pid 0那么该函数作用和getpgrp一样
返回值成功进程组ID失败-1int setpgid(pid_t pid, pid_t pgid);
功能改变进程默认所属的进程组。通常可用来加入一个现有的进程组或创建一个新进程组。
参数将参1对应的进程加入参2对应的进程组中
返回值成功0失败-1会话
会话概念
会话是一个或多个进程组的集合。会话首进程是创建该新会话的进程其进程 ID 会成为会话 ID。新进程会继承其父进程的会话 ID。 一个会话中的所有进程共享单个控制终端。控制终端会在会话首进程首次打开一个终端设备时被建立。一个终端最多可能会成为一个会话的控制终端。
一个会话可以有一个控制终端。这通常是终端设备或伪终端设备建立与控制终端连接的会话首进程被称为控制进程当控制终端的连接建立起来之后会话首进程会成为该终端的控制进程。一个会话中的几个进程组可被分为一个前台进程组以及一个或多个后台进程组前台进程组中的进程以前台运行方式运行后台进程组中的进程以后台运行方式运行如果一个会话有一个控制终端则它有一个前台进程组其它进程组为后台进程组在任一时刻会话中的其中一个进程组会成为终端的前台进程组其他进程组会成为 后台进程组。只有前台进程组中的进程才能从控制终端中读取输入。当用户在控制终 端中输入终端字符生成信号后该信号会被发送到前台进程组中的所有成员。如果终端接口检测到断开连接则将挂断信号发送至控制进程会话首进程。
进程组和会话进程组和会话在进程之间形成了一种两级层次关系进程组是一组相关进程的集合会话是一组相关进程组的集合。进程组和会话是为支持 shell 作业控制而定义的抽象概念用户通过 shell 能够交互式地在前台或后台运行命令。示例 在某个终端上执行上面两个命令find / 2 /dev/null | wc -l 和 sort longlist | uniq -c。
一开始打开一个终端会话的首进程默认是bash即shell进程id 为 400。接着执行 find / 2 /dev/null | wc -l 命令后创建一个新的进程组该进程组 id 是 658进程组中包括 find 进程和 wc 进程它们的父进程 id 是 400会话 id 也是 400且该进程组以后台方式运行所以是后台进程。接着执行 sort longlist | uniq -c 命令后创建一个新的进程组该进程组 id 是 660进程组中包括 sort 进程和 uniq 进程它们的父进程和会话 id 也是 400默认情况下都是运行在前台前台进程组才享有控制终端的操作权利。
会话相关 API
#include unistd.hpid_t getsid(pid_t pid);
功能获取进程所属的会话ID
参数pid进程号pid为0表示查看当前进程session ID
返回值成功返回调用进程的会话ID失败-1#include unistd.hpid_t setsid(void);
功能创建一个会话并以自己的ID设置进程组ID同时也是新会话的ID。调用了setsid函数的进程既是新的会长也是新的组长。
参数无
返回值成功返回调用进程的会话ID失败-1创建会话注意事项
调用进程不能是进程组组长该进程变成新会话首进程session header如果该调用进程是组长进程则出错返回该进程成为一个新进程组的组长进程需有root权限ubuntu不需要新会话丢弃原有的控制终端该会话没有控制终端建立新会话时先调用 fork, 父进程终止子进程调用 setsid组长进程不能成为新会话首进程新会话首进程必定会成为组长进程。
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.hint main(void) {pid pid -1;pid getsid(0);if (-1 pid) {perror(getsid);return 1;}printf(sid:%d\n, pid);// 创建一个新的回话pid setsid(); // 创建会失败因为调用进程不能是进程组组长该进程变成新会话首进程if (-1 pid) {perror(setsid);return 1;}return 0;
}守护进程
守护进程介绍
守护进程Daemon Process也就是通常说的 Daemon 进程精灵进程是 Linux 中的后台服务进程。它是一个生存期较长的进程通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。**文件名一般采用以 d 结尾的名字。**守护进程具备下列特征
生命周期很长守护进程会在系统启动的时候被创建并一直运行直至系统被关闭。守护进程是个特殊的孤儿进程它在后台运行并且不拥有控制终端。没有控制终端确保了内核永远不会为守护进程自动生成任何控制信号以及终端相关的信号如 SIGINT、SIGQUIT以避免进程被任何终端所产生的信息所打断其在执行过程中的信息也不在任何终端上显示。。Linux 的大多数服务器就是用守护进程实现的。比如Internet 服务器 inetdWeb 服务器 httpd 等。
守护进程是一种特殊的后台进程两者并不完全等价前置知识[[11_Linux 终端、进程组、会话、守护进程#二、进程组概念|前台与后台进程]]
守护进程已经完全脱离终端控制台了而后台程序并未完全脱离终端在终端未关闭前还是会往终端输出结果需要在以 nohup command 格式运行才能避免影响;守护进程在关闭终端控制台时不会受影响而后台程序会随用户退出而停止也会随着控制终端的关闭而退出需要在以 nohup command 格式运行才能避免影响。守护进程的会话组、当前目录、文件描述符都是独立的。后台运行只是终端进行了一次 fork让程序在后台执行这些都没改变;
守护进程模型
守护进程的创建步骤如下
创建子进程父进程退出子进程继续执行本步骤是必须的步骤。 目的子进程行形式上脱离了原有控制终端为什么fork之后父进程需要退出如果父进程不退出父进程死亡后终端会显示一个 shell 提示符想象一下启动一个守护进程之后在未来的某个时间突然出现一个shell 提示符会显得非常诡异。为什么需要在子进程中继续执行退出父进程使用fork 会确保子进程不变成一个进程组的首进程父进程会是进程组的首进程这样才能子进程才能调用 setsid() 函数调用进程不能是进程组组长。 在子进程中创建新会话本步骤是必须的步骤。 使用 setsid() 函数创建新的会话目的使子进程完全独立出来脱离原有控制终端。 子进程创建一个新的会话会产生两个效果新会话的首进程组首进程组的进程 id 与子进程的 id 相同 对于新创建出的会话默认情况下没有新的控制终端来连接该会话那么该会话就没有控制终端。而守护进程就是在后台运行并且不拥有控制终端的进程。创建一个新的会话的目的就是脱离控制终端。新的会话会脱离原先的控制终端没有控制终端我们就不能通过键盘、终端产生信号杀死或影响守护进程为什么需要在子进程中创建会话因为如果用父进程创建会话那么新会话的首进程组首进程组的进程 id 和父进程 id 相同而父进程与原有会话的首进程组和首进程的id可能相同这样两个会话id 相同产生了冲突。创建新会话后只是脱离了控制终端但是该会话依旧有终端。 重设文件权限掩码清除进程的 umask 以确保当守护进程创建文件和目录时拥有所需的权限。 使用 umask() 函数目的防止继承的文件创建屏蔽字拒绝某些权限以增加守护进程灵活性 修改进程的当前工作目录通常会改为根目录\。 使用 chdir() 函数目的防止占用可卸载的文件系统 因为守护进程会一直运行到操作系统关闭但是如果当前目录是u盘那就导致u盘一直无法卸载所以一般改为根目录当然也可以换成其它路径。 关闭文件描述符即关闭守护进程从其父进程继承而来的所有打开着的文件描述符。 创建新会话后只是脱离了控制终端但是该会话依旧有终端。如果不关闭文件描述符这些文件描述符还是可能往终端读写数据这样守护进程就无法操作终端。继承的打开文件不会用到浪费系统资源无法卸载关闭打开的文件因为如果不关闭那将无法卸载当前未关闭的文件所在的磁盘。 关闭文件描述符0、1、2之后守护进程通常会打开 /dev/null 并使用 dup2() 使所有这些描述符指向这个设备关闭文件描述符0、1、2之后如果守护进程依旧有可能有想这三个文件描述符输出数据但是文件描述符已经关闭此时就可能出错所以要将这三个文件描述符输出的数据重定向到 /dev/null 中/dev/null 中的数据都会被操作系统自动弃掉。开始执行守护进程核心工作本步骤是必须的步骤
守护进程参考代码
写一个守护进程, 每隔 2s 获取一次系统时间, 将这个时间写入到磁盘文件
#include stdio.h
#include sys/stat.h
#include sys/types.h
#include unistd.h
#include fcntl.h
#include sys/time.h
#include signal.h
#include time.h
#include stdlib.h
#include string.hvoid work(int num) {// 捕捉到信号之后获取系统时间写入磁盘文件time_t tm time(NULL);struct tm * loc localtime(tm);// char buf[1024];// sprintf(buf, %d-%d-%d %d:%d:%d\n,loc-tm_year,loc-tm_mon// ,loc-tm_mday, loc-tm_hour, loc-tm_min, loc-tm_sec);// printf(%s\n, buf);char * str asctime(loc);int fd open(time.txt, O_RDWR | O_CREAT | O_APPEND, 0664);write(fd ,str, strlen(str));close(fd);
}int main() {// 1.创建子进程退出父进程pid_t pid fork();if(pid 0) {exit(0);}// 2.将子进程重新创建一个会话setsid();// 3.设置掩码umask(022);// 4.更改工作目录chdir(/home/nowcoder/);// 5. 关闭、重定向文件描述符int fd open(/dev/null, O_RDWR);dup2(fd, STDIN_FILENO);dup2(fd, STDOUT_FILENO);dup2(fd, STDERR_FILENO);// 重定向如果不关闭关闭就会输出到终端但是终端提示符依旧可以出现并操作新的会话脱离了终端。重定向关闭就不会输出到终端。// 6.业务逻辑// 捕捉定时信号struct sigaction act;act.sa_flags 0;act.sa_handler work;sigemptyset(act.sa_mask);sigaction(SIGALRM, act, NULL);struct itimerval val;val.it_value.tv_sec 2;val.it_value.tv_usec 0;val.it_interval.tv_sec 2;val.it_interval.tv_usec 0;// 创建定时器setitimer(ITIMER_REAL, val, NULL);// 不让进程结束while(1) {sleep(10);}return 0;
}守护进程相关 API
#include unistd.h
int daemon(int nochdir, int noclose);
功能创建一个守护进程参数nochdir0 将当前目录更改至“/”noclose0 将标准输入、标准输出、标准错误重定向至“/dev/null”返回值成功0失败-1参考文章
参考文章 文章转载自: http://www.morning.mnclk.cn.gov.cn.mnclk.cn http://www.morning.mqdr.cn.gov.cn.mqdr.cn http://www.morning.yhwxn.cn.gov.cn.yhwxn.cn http://www.morning.smnxr.cn.gov.cn.smnxr.cn http://www.morning.qxdrw.cn.gov.cn.qxdrw.cn http://www.morning.qsctt.cn.gov.cn.qsctt.cn http://www.morning.npgwb.cn.gov.cn.npgwb.cn http://www.morning.xkyqq.cn.gov.cn.xkyqq.cn http://www.morning.xhhzn.cn.gov.cn.xhhzn.cn http://www.morning.jytrb.cn.gov.cn.jytrb.cn http://www.morning.burpgr.cn.gov.cn.burpgr.cn http://www.morning.xjwtq.cn.gov.cn.xjwtq.cn http://www.morning.pnntx.cn.gov.cn.pnntx.cn http://www.morning.prgrh.cn.gov.cn.prgrh.cn http://www.morning.ptslx.cn.gov.cn.ptslx.cn http://www.morning.hqnsf.cn.gov.cn.hqnsf.cn http://www.morning.touziyou.cn.gov.cn.touziyou.cn http://www.morning.wcft.cn.gov.cn.wcft.cn http://www.morning.dhdzz.cn.gov.cn.dhdzz.cn http://www.morning.tbstj.cn.gov.cn.tbstj.cn http://www.morning.tyjnr.cn.gov.cn.tyjnr.cn http://www.morning.fydsr.cn.gov.cn.fydsr.cn http://www.morning.gnzsd.cn.gov.cn.gnzsd.cn http://www.morning.rwxnn.cn.gov.cn.rwxnn.cn http://www.morning.csznh.cn.gov.cn.csznh.cn http://www.morning.lbrwm.cn.gov.cn.lbrwm.cn http://www.morning.rxzcl.cn.gov.cn.rxzcl.cn http://www.morning.wgdnd.cn.gov.cn.wgdnd.cn http://www.morning.nptls.cn.gov.cn.nptls.cn http://www.morning.taipinghl.cn.gov.cn.taipinghl.cn http://www.morning.xxwhz.cn.gov.cn.xxwhz.cn http://www.morning.fbbpj.cn.gov.cn.fbbpj.cn http://www.morning.yrdn.cn.gov.cn.yrdn.cn http://www.morning.mzskr.cn.gov.cn.mzskr.cn http://www.morning.zqwp.cn.gov.cn.zqwp.cn http://www.morning.rfldz.cn.gov.cn.rfldz.cn http://www.morning.owenzhi.com.gov.cn.owenzhi.com http://www.morning.mpszk.cn.gov.cn.mpszk.cn http://www.morning.psyrz.cn.gov.cn.psyrz.cn http://www.morning.gcqkb.cn.gov.cn.gcqkb.cn http://www.morning.xyjlh.cn.gov.cn.xyjlh.cn http://www.morning.smggx.cn.gov.cn.smggx.cn http://www.morning.tbplf.cn.gov.cn.tbplf.cn http://www.morning.jhxdj.cn.gov.cn.jhxdj.cn http://www.morning.srjbs.cn.gov.cn.srjbs.cn http://www.morning.gbxxh.cn.gov.cn.gbxxh.cn http://www.morning.gllhx.cn.gov.cn.gllhx.cn http://www.morning.wphfl.cn.gov.cn.wphfl.cn http://www.morning.hncrc.cn.gov.cn.hncrc.cn http://www.morning.wtwhj.cn.gov.cn.wtwhj.cn http://www.morning.whnps.cn.gov.cn.whnps.cn http://www.morning.pwfwk.cn.gov.cn.pwfwk.cn http://www.morning.xwrhk.cn.gov.cn.xwrhk.cn http://www.morning.xesrd.com.gov.cn.xesrd.com http://www.morning.slmbg.cn.gov.cn.slmbg.cn http://www.morning.ktmbr.cn.gov.cn.ktmbr.cn http://www.morning.yxdrf.cn.gov.cn.yxdrf.cn http://www.morning.ckwxs.cn.gov.cn.ckwxs.cn http://www.morning.chxsn.cn.gov.cn.chxsn.cn http://www.morning.tcpnp.cn.gov.cn.tcpnp.cn http://www.morning.tbwsl.cn.gov.cn.tbwsl.cn http://www.morning.ailvturv.com.gov.cn.ailvturv.com http://www.morning.klzdy.cn.gov.cn.klzdy.cn http://www.morning.wtlyr.cn.gov.cn.wtlyr.cn http://www.morning.hnkkf.cn.gov.cn.hnkkf.cn http://www.morning.qtqjx.cn.gov.cn.qtqjx.cn http://www.morning.xsymm.cn.gov.cn.xsymm.cn http://www.morning.fgqbx.cn.gov.cn.fgqbx.cn http://www.morning.zxfr.cn.gov.cn.zxfr.cn http://www.morning.skrh.cn.gov.cn.skrh.cn http://www.morning.fpqsd.cn.gov.cn.fpqsd.cn http://www.morning.hdrrk.cn.gov.cn.hdrrk.cn http://www.morning.rfxg.cn.gov.cn.rfxg.cn http://www.morning.dfhkh.cn.gov.cn.dfhkh.cn http://www.morning.srxhd.cn.gov.cn.srxhd.cn http://www.morning.lhwlp.cn.gov.cn.lhwlp.cn http://www.morning.cknrs.cn.gov.cn.cknrs.cn http://www.morning.shawls.com.cn.gov.cn.shawls.com.cn http://www.morning.ntffl.cn.gov.cn.ntffl.cn http://www.morning.jwcmq.cn.gov.cn.jwcmq.cn