版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、进程进程进程进程进程控制的相关函数进程控制的相关函数v进程的进程的创建创建 派生进程:派生进程:fork(),vfork(); 创建执行其他程序的进程:创建执行其他程序的进程:exec();(选学)(选学) Linux系统特有的调用:系统特有的调用:_ _clone(); (选学)(选学)v进程的进程的等待等待 wait(),waitpid();v进程的进程的终止终止 exit(),atexit(),on_exit(),abort(),_exit();v其他函数其他函数 system() (选学)(选学) ,getpid()。进程的创建进程的创建vfork()函数函数#include #inc
2、lude pid_t fork(void); vfork在英文中是在英文中是“分叉分叉”的意思。一个进程在运行中,的意思。一个进程在运行中,如果使用了如果使用了fork ,就产生了另一个进程,于是进程,就产生了另一个进程,于是进程就就“分叉分叉”了。当前进程为父进程,通过了。当前进程为父进程,通过fork()会产会产生一个子进程。对于父进程,返回生一个子进程。对于父进程,返回子程序的进程号子程序的进程号,而对于子程序则返回而对于子程序则返回0,这就是,这就是fork函数的特点函数的特点 “调调用一次,返回两次用一次,返回两次”,出错则返回,出错则返回-1。 fork函数是函数是Unix系统最杰
3、出的成就之一。系统最杰出的成就之一。进程的创建进程的创建vfork函数实例函数实例以及说明:以及说明: 因父进程和子进程的运行无关,父进程或子进程因父进程和子进程的运行无关,父进程或子进程返回的顺序随机的,因此运行结果不唯一。返回的顺序随机的,因此运行结果不唯一。vvfork()函数函数以及以及实例实例 vfork创建新进程的主要目的在于用创建新进程的主要目的在于用exec函数执行函数执行另外的程序,实际上,在没调用另外的程序,实际上,在没调用exec或或exit之前子之前子进程的运行中是与父进程共享数据段的。在进程的运行中是与父进程共享数据段的。在vfork调用中,子进程先运行,父进程挂起,
4、直到子进调用中,子进程先运行,父进程挂起,直到子进程调用程调用exec或或exit,在这以后,父子进程的执行顺,在这以后,父子进程的执行顺序不再有限制。序不再有限制。进程的创建进程的创建vfork函数实例函数实例以及说明:以及说明: 因父进程和子进程的运行无关,父进程或子进程因父进程和子进程的运行无关,父进程或子进程返回的顺序随机的,因此运行结果不唯一。返回的顺序随机的,因此运行结果不唯一。vvfork()函数函数以及以及实例实例 vfork创建新进程的主要目的在于用创建新进程的主要目的在于用exec函数执行函数执行另外的程序,实际上,在没调用另外的程序,实际上,在没调用exec或或exit之
5、前子之前子进程的运行中是与父进程共享数据段的。在进程的运行中是与父进程共享数据段的。在vfork调用中,子进程先运行,父进程挂起,直到子进调用中,子进程先运行,父进程挂起,直到子进程调用程调用exec或或exit,在这以后,父子进程的执行顺,在这以后,父子进程的执行顺序不再有限制。序不再有限制。进程的创建进程的创建fork运行结果运行结果vfork运行结果运行结果进程的创建进程的创建fork运行结果运行结果vfork运行结果运行结果进程的创建进程的创建(选学)(选学)vexec()函数族函数族v用用fork创建子进程后执行的是和父进程相同的程序创建子进程后执行的是和父进程相同的程序(但有可能执
6、行不同的代码分支但有可能执行不同的代码分支),子进程往往要调用,子进程往往要调用一种一种exec函数以执行另一个程序。当进程调用一种函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用并不创建新进程,所以调用exec前后该进程的前后该进程的id并未并未改变。改变。进程的创建进程的创建(选学)(选学)v其实有六种以其实有六种以exec开头的函数,统称开头的函数,统称exec函数:函数:#include in
7、t 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 execve(const char *path, char *const
8、 argv, char *const envp); 进程的创建进程的创建(选学)(选学)v这些函数如果调用成功则加载新的程序从启动代码这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回,如果调用出错则返回开始执行,不再返回,如果调用出错则返回-1,所以,所以exec函数函数只有出错的返回值而没有成功的返回值只有出错的返回值而没有成功的返回值。v在在exec函数族中,后缀函数族中,后缀l、v、p、e添加到添加到exec后,所后,所指定的函数将具有某种操作能力有后缀:指定的函数将具有某种操作能力有后缀:vp(path)时,函数可以利用时,函数可以利用DOS的的PATH变量查找子变量查找
9、子程序文件。程序文件。 假如你希望执行命令假如你希望执行命令 /bin/cat /etc/passwd /etc/group(通过(通过cat命令查看命令查看/etc/passwd和和/etc/group的内容)的内容)进程的创建进程的创建(选学)(选学)vl(list)时,希望接收以逗号分隔的参数列表,列表以时,希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志。指针作为结束标志。execl( /bin/cat, /etc/passed, /etc/group, NULL);vv(vector)时,希望接收到一个以时,希望接收到一个以NULL结尾的字符串结尾的字符串数组的指针。数组
10、的指针。char* argv = /bin/cat, /etc/passed, /etc/group, NULLexecv( /bin/cat, argv );ve(environment)时,函数传递参数时,函数传递参数envp,允许改变子,允许改变子进程的环境,无后缀进程的环境,无后缀e时,子进程使用当前程序的环时,子进程使用当前程序的环境。境。envp也是一个以也是一个以NULL结尾的字符串数组指针。结尾的字符串数组指针。进程的创建进程的创建(选学)(选学)vexecl和和execlp完全相同,完全相同,execv和和execvp完全相同。完全相同。vexecl()和和execv()要求
11、提供可执行文件的绝对或相对路要求提供可执行文件的绝对或相对路径名,而径名,而execlp()和和execvp()使用使用$PATH环境变量查环境变量查找找path。进程的创建进程的创建(选学)(选学)v一个完整的例子一个完整的例子 #include #include int main(void) execlp(ps, ps, -o, pid,ppid,pgrp,session,tpgid,comm, NULL); perror(exec ps); exit(1); rootlocalhost ch06# ./execlp PID PPID PGRP SESS TPGID COMMAND 912
12、5 9122 9125 9125 9937 bash 9937 9125 9937 9125 9937 ps进程的创建进程的创建(选学)(选学)v由于由于exec函数只有错误返回值,只要返回了一定是出函数只有错误返回值,只要返回了一定是出错了,所以不需要判断它的返回值,直接在后面调错了,所以不需要判断它的返回值,直接在后面调用用perror即可。即可。v注意在调用注意在调用execlp时传了两个时传了两个ps参数,第一个参数,第一个ps是程序名,是程序名,execlp函数要在函数要在PATH环境变量中找到这环境变量中找到这个程序并执行它,而第二个个程序并执行它,而第二个ps是第一个命令行参是第
13、一个命令行参数,数,execlp函数并不关心它的值,只是简单地把它传函数并不关心它的值,只是简单地把它传给给ps程序,程序,ps程序可以通过程序可以通过main函数的函数的argv0取到取到这个参数。这个参数。v调用调用exec后,原来打开的文件描述符仍然是打开的。后,原来打开的文件描述符仍然是打开的。利用这一点可以实现利用这一点可以实现I/O重定向。重定向。实例实例execve.c进程的创建进程的创建(选学)(选学)vLinux特有的调用特有的调用clonevclone是是Linux2.0以后才具备的新功能,它较以后才具备的新功能,它较fork更强更强(可认为可认为fork是是clone要实
14、现的一部分要实现的一部分),可以使得创建,可以使得创建的子进程共享父进程的资源,并且要使用此函数必的子进程共享父进程的资源,并且要使用此函数必须在编译内核时设置须在编译内核时设置clone_actually_works_ok选项。选项。vclone函数的原型为:函数的原型为:inlude int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);v此函数返回创建进程的此函数返回创建进程的PID,函数中的,函数中的flags标志用于标志用于设置创建子进程时的相关选项,具体含义如下表:设置创建子进程时的相关选项,具体
15、含义如下表:进程的创建进程的创建(选学)(选学)标志标志含义含义CLONE_PARENT创建的子进程的父进程是调用者的父进程,新进程与创建它创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了的进程成了“兄弟兄弟”而不是而不是“父子父子”CLONE_FS子进程与父进程共享相同的文件系统,包括子进程与父进程共享相同的文件系统,包括root、当前目录、当前目录、umaskCLONE_FILES子进程与父进程共享相同的文件描述符(子进程与父进程共享相同的文件描述符(file descriptor)表)表CLONE_NEWNS在新的在新的namespace启动子进程,启动子进程,namesp
16、ace描述了进程的文件描述了进程的文件hierarchyCLONE_SIGHAND子进程与父进程共享相同的信号处理(子进程与父进程共享相同的信号处理(signal handler)表)表CLONE_PTRACE若父进程被若父进程被trace,子进程也被,子进程也被traceCLONE_VFORK父进程被挂起,直至子进程释放虚拟内存资源父进程被挂起,直至子进程释放虚拟内存资源CLONE_VM子进程与父进程运行于相同的内存空间子进程与父进程运行于相同的内存空间CLONE_PID子进程在创建时子进程在创建时PID与父进程一致与父进程一致CLONE_THREADLinux 2.4中增加以支持中增加以支
17、持POSIX线程标准,子进程与父进程共线程标准,子进程与父进程共享相同的线程群享相同的线程群进程等待进程等待v在多进程处理时,用户可能需要用到有关进程等待在多进程处理时,用户可能需要用到有关进程等待的操作。这种等待可以是进程组成员间的等待,也的操作。这种等待可以是进程组成员间的等待,也可以是父进程对子进程的等待。可以是父进程对子进程的等待。 例如,当一个进程结束时,例如,当一个进程结束时,Linux系统将产生一个系统将产生一个SIGCHLD信号通知其父进程。在父进程未查询子信号通知其父进程。在父进程未查询子进程结束的原因时,该子进程虽然停止了,但并进程结束的原因时,该子进程虽然停止了,但并未完
18、全结束。此时该子进程被称为未完全结束。此时该子进程被称为僵尸进程僵尸进程(zombie process)这时的处理方法之一就是使用进这时的处理方法之一就是使用进程等待的系统调用程等待的系统调用 wait 和和waitpid。进程等待进程等待vwait()函数函数#include #include pid_t wait(int *status); 进程一旦调用了进程一旦调用了wait,就立即,就立即阻塞自己阻塞自己,由由wait()函数分析是否当前的某个子进程已经退出,函数分析是否当前的某个子进程已经退出,如如果果让它找到了这样一个已经变成僵尸的子进程,让它找到了这样一个已经变成僵尸的子进程,w
19、ait就会收集这个子进程的信息,并把它就会收集这个子进程的信息,并把它彻底销彻底销毁后返回毁后返回;如果没有找到这样一个子进程,;如果没有找到这样一个子进程,wait就会一直就会一直阻塞阻塞在这里,直到有一个出现为止。可在这里,直到有一个出现为止。可认为认为wait()系统调用的作用就是负责回收僵尸进程系统调用的作用就是负责回收僵尸进程 。进程等待进程等待 因为在下列两个事件都已经发生的情况下进程才因为在下列两个事件都已经发生的情况下进程才会完全终止:会完全终止: (1)进程自己已经退出进程自己已经退出(或已经被一个信号杀死或已经被一个信号杀死) (2)它的父进程已经执行了它的父进程已经执行了
20、WAIT系统调用以观系统调用以观察发生了什么。如果已经退出或被杀死而它的察发生了什么。如果已经退出或被杀死而它的父进程还没有为它执行父进程还没有为它执行WAIT的进程将进入某的进程将进入某种挂起状态,有时被称为种挂起状态,有时被称为僵死状态僵死状态(Zombie State),这种进程不再参与调度,它的报警时钟,这种进程不再参与调度,它的报警时钟被关闭,但它仍将留在进程表中,它的内存被被关闭,但它仍将留在进程表中,它的内存被释放。僵死是一种临时状态,很少会持续较长释放。僵死是一种临时状态,很少会持续较长的时间,当父进程最后执行的时间,当父进程最后执行WAIT时,将释放时,将释放进程表项,并通知
21、文件系统和内核。进程表项,并通知文件系统和内核。进程等待进程等待v对于参数对于参数status是一个指向是一个指向int型的变量,用来保存子型的变量,用来保存子进程退出时的状态(例如子进程中有进程退出时的状态(例如子进程中有exit(2009)或或return(2009),那么这个变量里的某些二进制位存放,那么这个变量里的某些二进制位存放的就是的就是2009,也就是子进程的返回值),也就是子进程的返回值),但如果我但如果我们对这个子进程是如何死掉的毫不在意,只想把这们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我个僵尸进程消灭掉,(事实上绝大多数情况下,
22、我们都会这样想),我们就可以设定这个参数为们都会这样想),我们就可以设定这个参数为NULL,就象下面这样:就象下面这样:pid = wait(NULL); v如果成功,如果成功,wait会返回被收集的会返回被收集的子进程的进程子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时如果调用进程没有子进程,调用就会失败,此时wait返回返回-1,同时,同时errno被置为被置为ECHILD。进程等待进程等待vWati()函数实例:函数实例:wait1.cv编译并运行编译并运行:$ gcc wait1.c -o wait1$ ./wait1This is child process with
23、pid of 1508I catched a child process with pid of 1508v可以明显注意到,在第可以明显注意到,在第2行结果打印出来前有行结果打印出来前有10 秒钟秒钟的等待时间,这就是我们设定的让子进程睡眠的时的等待时间,这就是我们设定的让子进程睡眠的时间,只有子进程从睡眠中苏醒过来,它才能正常退间,只有子进程从睡眠中苏醒过来,它才能正常退出,也就才能被父进程捕捉到。其实这里我们不管出,也就才能被父进程捕捉到。其实这里我们不管设定子进程睡眠的时间有多长,父进程都会一直等设定子进程睡眠的时间有多长,父进程都会一直等待下去。待下去。进程等待进程等待v如果参数如果参
24、数status的值不是的值不是NULL,wait就会把子进程就会把子进程退出时的状态取出并存入其中,这是一个整数值,退出时的状态取出并存入其中,这是一个整数值,指出了子进程是正常退出还是被非正常结束的(一指出了子进程是正常退出还是被非正常结束的(一个进程也可以被其他进程用信号结束),以及正常个进程也可以被其他进程用信号结束),以及正常结束时的返回值,或被哪一个信号结束的等信息。结束时的返回值,或被哪一个信号结束的等信息。由于这些信息被存放在一个整数的不同二进制位中,由于这些信息被存放在一个整数的不同二进制位中,所以用常规的方法读取会非常麻烦,人们就设计了所以用常规的方法读取会非常麻烦,人们就设
25、计了一套专门的宏(一套专门的宏(macro)来完成这项工作,下面我们)来完成这项工作,下面我们来学习一下其中最常用的两个:来学习一下其中最常用的两个:进程等待进程等待1、WIFEXITED(status) 这个宏用来指出子进程是否为这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。正常退出的,如果是,它会返回一个非零值。 请注意,虽然名字一样,这里的参数请注意,虽然名字一样,这里的参数status并不同并不同于于wait唯一的参数唯一的参数-指向整数的指针指向整数的指针status,而是,而是那个指针所指向的整数,切记不要搞混了。那个指针所指向的整数,切记不要搞混了。2、WEX
26、ITSTATUS(status) 当当WIFEXITED返回非零返回非零值时,我们可以用这个宏来提取子进程的返回值,值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用如果子进程调用exit(5)退出,退出,WEXITSTATUS(status) 就会返回就会返回5;如果子进程调用;如果子进程调用exit(7),WEXITSTATUS(status)就会返回就会返回7。请注意,如果。请注意,如果进程不是正常退出的,也就是说,进程不是正常退出的,也就是说, WIFEXITED返返回回0,这个值就毫无意义,这个值就毫无意义进程等待进程等待vwait2.c实例实例。v编译并运行编译并运行: r
27、ootlocalhost ch06# gcc -o wait2 wait2.crootlocalhost ch06# ./wait2This is child process with pid of 12668.the child process 12668 exit normally.the return code is 3. 父进程准确捕捉到了子进程的返回值父进程准确捕捉到了子进程的返回值3,并把它打,并把它打印了出来。印了出来。 进程等待进程等待vwaitpid()函数函数vwaitpid() 系统调用在系统调用在Linux函数库中的原型是:函数库中的原型是: #include /#in
28、clude pid_t waitpid(pid_t pid,int *status,int options); v从本质上讲,系统调用从本质上讲,系统调用waitpid和和wait的作用是完全的作用是完全相同的,但相同的,但waitpid多出了两个可由用户控制的参数多出了两个可由用户控制的参数pid和和options,从而为我们编程提供了另一种更灵活,从而为我们编程提供了另一种更灵活的方式。的方式。v下面我们就来详细介绍一下这两个参数:下面我们就来详细介绍一下这两个参数:进程等待进程等待vpid参数参数 pid0时,时,只等待进程只等待进程ID等于等于pid的子进程的子进程,不管,不管其它已经
29、有多少子进程运行结束退出了,只要指其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,定的子进程还没有结束,waitpid就会一直等下去。就会一直等下去。 pid=-1时,时,等待任何一个子进程退出等待任何一个子进程退出,没有任何限,没有任何限制,此时制,此时waitpid和和wait的作用一模一样。的作用一模一样。 pid=0时,时,等待等待同一个进程组同一个进程组中的任何子进程中的任何子进程,如,如果子进程已经加入了别的进程组,果子进程已经加入了别的进程组,waitpid不会对不会对它做任何理睬。它做任何理睬。 pid-1时,时,等待等待一个指定进程组一个指定进程组中的任何子进
30、程中的任何子进程,这个进程组的这个进程组的ID等于等于pid的绝对值。的绝对值。 进程等待进程等待voptions参数参数 options提供了一些额外的选项来控制提供了一些额外的选项来控制waitpid,目前在,目前在Linux中只支持中只支持WNOHANG和和WUNTRACED两个选两个选项,这是两个常数,可以用项,这是两个常数,可以用|运算符把它们连接起来运算符把它们连接起来使用,比如:使用,比如:ret=waitpid(-1,NULL,WNOHANG | WUNTRACED); 如果我们不想使用它们,也可以把如果我们不想使用它们,也可以把options设为设为0,如:,如: ret=w
31、aitpid(-1,NULL,0); 如果使用了如果使用了WNOHANG参数调用参数调用waitpid,即使没有,即使没有子进程退出,它也会立即返回,不会像子进程退出,它也会立即返回,不会像wait那样永远那样永远等下去。等下去。 而而WUNTRACED参数,由于涉及到一些跟踪调试方参数,由于涉及到一些跟踪调试方面的知识,加之极少用到,这里就不多讲。面的知识,加之极少用到,这里就不多讲。进程等待进程等待v Waitpid()函数实例函数实例v 编译并运行:编译并运行:$ gcc waitpid.c -o waitpid$ ./waitpidNo child exitedNo child exi
32、tedNo child exitedNo child exitedNo child exitedNo child exitedNo child exitedNo child exitedNo child exitedNo child exitedsuccessfully get child 1526v父进程经过父进程经过10次失败的尝次失败的尝试之后,终于收集到了退试之后,终于收集到了退出的子进程。出的子进程。进程等待进程等待v父进程调用父进程调用wait或或waitpid时可能会:时可能会: 阻塞阻塞(如果它的所有子进程都还在运行)。(如果它的所有子进程都还在运行)。 带子进程的终止信息带子
33、进程的终止信息立即返回(如果一个子进程立即返回(如果一个子进程已终止,正等待父进程读取其终止信息)。已终止,正等待父进程读取其终止信息)。 出错出错立即返回(如果它没有任何子进程)。立即返回(如果它没有任何子进程)。v这两个函数的区别是:这两个函数的区别是: 如果父进程的所有子进程都还在运行,调用如果父进程的所有子进程都还在运行,调用wait将使父进程将使父进程阻塞阻塞,而调用,而调用waitpid时如果在时如果在options参数中指定参数中指定WNOHANG可以使父进程可以使父进程不阻塞而立不阻塞而立即返回即返回0。 wait等待第一个终止的子进程等待第一个终止的子进程,而,而waitpi
34、d可以通可以通过过pid参数指定参数指定等待哪一个子进程。等待哪一个子进程。进程的终止进程的终止v进程结束可通过相应的函数实现:进程结束可通过相应的函数实现:vvoid exit(int status); vvoid _exit(int status); 终止正在运行的程序,关闭所有被该文件打开的终止正在运行的程序,关闭所有被该文件打开的文件描述符文件描述符 _exit与与exit不同的是可以关闭一些不同的是可以关闭一些Linux下特有的下特有的退出句柄。退出句柄。vint atexit(void (*function)(void); 用于注册一个不带参数也没有返回值的函数以供用于注册一个不带
35、参数也没有返回值的函数以供程序正常退出时被调用。参数程序正常退出时被调用。参数function是指向所调是指向所调用程序的文件指针。调用成功返回用程序的文件指针。调用成功返回0,否则返回,否则返回-1,并将并将errno设置为相应值设置为相应值进程的终止进程的终止vint on_exit(void (*function)(int,void *),void *arg); 作用与作用与atexit类似,不同是其注册的函数具有参数,类似,不同是其注册的函数具有参数,退出状态和参数退出状态和参数arg都是传递给该函数使用。都是传递给该函数使用。vvoid abort(void); 用来发送一个用来发送
36、一个SIGABRT信号,该信号将使当前进信号,该信号将使当前进程终止。程终止。vvoid assert( int expression ); 先先计算表达式计算表达式 expression ,如果其值为,如果其值为0,那么它,那么它先向先向stderr打印一条出错信息,然后通过调用打印一条出错信息,然后通过调用 abort 来终止程序运行。常用来检测某些参数是否来终止程序运行。常用来检测某些参数是否有不当情况出现,并在不当情况发生时以结束进有不当情况出现,并在不当情况发生时以结束进程作为相应处理。程作为相应处理。进程的终止进程的终止vatexit实例实例vassert实例实例system函数函
37、数(选学)(选学)vsystem函数是一个和操作系统紧密相关的函数。用户函数是一个和操作系统紧密相关的函数。用户可以使用它在自己的程序中调用系统提供的各种命可以使用它在自己的程序中调用系统提供的各种命令。令。 vsystem函数的说明如下:函数的说明如下: #include int system(const char *cmdstring); 参数参数cmdstring是一个字符串指针。是一个字符串指针。 如果如果cmd是一个空指针,则仅仅当命令处理程序是一个空指针,则仅仅当命令处理程序可用时,可用时,system返回非返回非0值。值。system函数函数(选学)(选学)v因为因为system在其实现中调用了在其实现中调用了fork,exec和和waitpid,因此有三种返回值:因此有三种返回值:1)如果如果fork失败或者失败或者waitp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024葡萄酒年份酒拍卖会组织与销售代理合同3篇
- 2024车辆保养维修中心服务承包合同
- 2024版路灯租赁合同书
- 2025年度厂房投资合作项目合同范本3篇
- 2024年跨国软件定制开发合同
- 2024风力发电项目投资建设合同
- 2024版云计算服务定制合同
- 2024年钢筋工程劳务承包专用合同
- 2024特岗教师招聘与聘用及培训与考核服务合同3篇
- 动物疫病检验技术知到智慧树章节测试课后答案2024年秋黑龙江农业经济职业学院
- 降低成本费用的措施
- 工程量确认单范本
- 洁净室工程行业深度分析
- 频谱仪N9020A常用功能使用指南
- 天津高考英语词汇3500
- 医疗质量检查分析及整改措施反馈
- psa制氮机应急预案
- 三年级下册数学教案-6练习五-北师大版
- 六年级作文指导暑假趣事经典课件
- 最敬业员工无记名投票选举表
- 建设工程质量检测作业指导书+仪器设备操作规程2021版
评论
0/150
提交评论