




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 实时信号之所以是可靠的,因为在进程阻塞该信号的时间内,发给该进程的所有实时信号会排队,而非实时信号则会合并为一个信号。早期的kill函数只能向特定的进程发送一个特定的信号,并且早期的信号处理函数也不能接受附加数据。siqueue和sigaction解决了这个问题。平时没有有机会使用实时信号,所以想体验下它的排队特性。 下面这个例子中,进程先屏蔽SIGINT和SIGRTMIN两个信号,其中SIGINT是非实时信号,而SIGRTMIN为实时信号,接着进程睡眠,睡眠完成之后再接触对这两个信号的屏蔽,此时可以比较对两种
2、信号的处理方式是否一样。#include <stdio.h>#include <string.h>#include <signal.h>#include <unistd.h>void sig_handler(int,siginfo_t*,void*);int main(int argc,char*argv) struct sigaction act; sigset_t newmask, oldmask; int rc; sig
3、emptyset(&newmask); /往信号集中添加一个非实时信号 sigaddset(&newmask, SIGINT); /往信号集中添加一个实时信号 sigaddset(&newmask, SIGRTMIN); /屏蔽实时信号SIGRTMIN sigprocmask(SIG_BLOCK, &newmask, &oldmask); act.sa_sigaction = sig_ha
4、ndler; act.sa_flags = SA_SIGINFO; if(sigaction(SIGINT, &act, NULL) < 0) printf("install sigal errorn"); if(sigaction(SIGRTMIN, &act, NULL) < 0)
5、160; printf("install sigal errorn"); printf("pid = %dn", getpid(); /进程睡眠,在此时间内的发给该进程的所有实时信号 /将排队,不会有信号丢失 sleep(20); /解除对SIGRTMIN信号的屏蔽 /信号处理函数将会被调用 sigprocmas
6、k(SIG_SETMASK, &oldmask, NULL); return 0;void sig_handler(int signum,siginfo_t *info,void *myact) if(signum = SIGINT) printf("Got a common signaln"); else printf("Got a real time sign
7、aln");将程序编译好之后,再开一个终端用于发送实时信号。ecyecy-geek:/pthreads$ ./sigqueue_receive pid = 8871进程开始睡眠在新的终端输入:ecyecy-geek:/pthreads$ kill -SIGRTMIN 8871ecyecy-geek:/pthreads$ kill -SIGRTMIN 8871ecyecy-geek:/pthreads$ kill -SIGRTMIN 8871ecyecy-geek:/pthreads$ kill -SIGRTMIN 8871连续发送四个SIGRTMIN,接着回到之前的终端,连续四次按下
8、"ctrl+c"。CCCC最后进程终于醒来,整个输出如下:pid = 8871CCCCGot a real time signalGot a real time signalGot a real time signalGot a real time signalGot a common signal果然接受到四个实时信号,并且四次调用了信号处理函数,而对于SIGINT,虽然也按下了四次"ctrl+c",但是进程对其只做一次处理。我发现这儿有个细节有点意思,这个例子中是先发实时信号后发非实时信号,所以信号处理函数先处理实时信号,如果只是按照顺序注册信号的话
9、,这很好理解,但是换一下,先按下了四次"ctrl+c"然后使用kill发四次实时信号,结果发现输出的结果仍然一样,这就有点怪了,这说明实时信号的优先级比非实时信号要高,内核每个进程的信号组成一个双向链表,实时信号插入的时候就不是随便插在尾部了。哎,不懂内核什么都要靠猜测,不爽在网上找到这样一段话: 信号的优先级:信号实质上是软中断,中断有优先级,信号也有优先级。如果一个进程有多个未决信号,则对于同一个未决的实时信号,内核将按照发送的顺序来递送信号。如果存在多个未决的实时信号,则值(或者说编号)越小的越先被递送。如果既存在不可靠信号,又存在可靠信号(实时信号),虽然POSIX
10、对这一情况没有明确规 定,但Linux系统和大多数遵循POSIX标准的操作系统一样,将优先递送不可靠信号。经过我反反复复地试验,我发现实验结果和上面描述的刚好相反,信号的编号越大越先被递送,一个进程如果处理SIGQUIT(3),SIGINT(2),SIGHUP(1)(通过"kill -l"可以查看信号的编号),那么先后给该进程发送SIGINT,SIGHUP,SIGQUIT,处理的顺序会是SIGQUIT,SIGINT,SIGHUP,不论改变这个三个信号的发送顺序,处理的顺序都是一样的。信号详解 博客分类: · linux linuxsignal 一 信号的
11、种类可靠信号与不可靠信号, 实时信号与非实时信号可靠信号就是实时信号, 那些从UNIX系统继承过来的信号都是非可靠信号, 表现在信号不支持排队,信号可能会丢失, 比如发送多次相同的信号, 进程只能收到一次. 信号值小于SIGRTMIN的都是非可靠信号.非可靠信号就是非实时信号, 后来, Linux改进了信号机制, 增加了32种新的信号, 这些信号都是可靠信号, 表现在信号支持排队, 不会丢失, 发多少次, 就可以收到多少次. 信号值位于 SIGRTMIN, SIGRTMAX 区间的都是可靠信号. 关于可靠信号, 还可以参考WIKI的一段话: Text代码
12、0;1. The real-time signals, ranging from SIGRTMIN to SIGRTMAX, are a set of signals that can be used for application-defined purposes. 2. Because SIGRTMIN may have different
13、 values on different Unix-like systems, applications should always refer to the signals in the form SIGRTMIN+n, where n is a constant integer expression. 3. The real-ti
14、me signals have a number of properties that differentiate them from other signals and make them suitable for application-defined purposes: 4. * Multiple instances of a
15、real-time signal can be sent to a process and all will be delivered. 5. * Real-time signals can be accompanied by an integer or pointer value (see sigqueue2).
16、0; 6. * Real-time signals are guaranteed to be delivered in the order they were emitted. The real-time signals, ranging from SIGRTMIN to SIGRTMAX, are a set of signals that can be used for application-defined purposes.B
17、ecause SIGRTMIN may have different values on different Unix-like systems, applications should always refer to the signals in the form SIGRTMIN+n, where n is a constant integer expression.The real-time signals have a number of properties that differentiate them from other signals and make them suitab
18、le for application-defined purposes:* Multiple instances of a real-time signal can be sent to a process and all will be delivered.* Real-time signals can be accompanied by an integer or pointer value (see sigqueue2).* Real-time signals are guaranteed to be delivered in the order they were emitted.
19、160; 命令行输入 kill -l, 可以列出系统支持的所有信号: C代码 1. > kill -l 2. 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 3. 6) SIGABRT 7) SIGBUS
20、160; 8) SIGFPE 9) SIGKILL 10) SIGUSR1 4. 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 5. 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT
21、;19) SIGSTOP 20) SIGTSTP 6. 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 7. 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO &
22、#160; 30) SIGPWR 8. 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 9. 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6
23、41) SIGRTMIN+7 42) SIGRTMIN+8 10. 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 11. 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51)
24、SIGRTMAX-13 52) SIGRTMAX-12 12. 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 13. 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61)
25、 SIGRTMAX-3 62) SIGRTMAX-2 14. 63) SIGRTMAX-1 64) SIGRTMAX > kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL10) SIGUSR111) SIGSEGV12) SIGUSR213) SIGPIPE14
26、) SIGALRM15) SIGTERM16) SIGSTKFLT17) SIGCHLD18) SIGCONT19) SIGSTOP20) SIGTSTP21) SIGTTIN22) SIGTTOU23) SIGURG24) SIGXCPU25) SIGXFSZ26) SIGVTALRM27) SIGPROF28) SIGWINCH29) SIGIO30) SIGPWR31) SIGSYS34) SIGRTMIN35) SIGRTMIN+136) SIGRTMIN+237) SIGRTMIN+338) SIGRTMIN+439) SIGRTMIN+540) SIGRTMIN+641) SIGR
27、TMIN+742) SIGRTMIN+843) SIGRTMIN+944) SIGRTMIN+1045) SIGRTMIN+1146) SIGRTMIN+1247) SIGRTMIN+1348) SIGRTMIN+1449) SIGRTMIN+1550) SIGRTMAX-1451) SIGRTMAX-1352) SIGRTMAX-1253) SIGRTMAX-1154) SIGRTMAX-1055) SIGRTMAX-956) SIGRTMAX-857) SIGRTMAX-758) SIGRTMAX-659) SIGRTMAX-560) SIGRTMAX-461) SIGRTMAX-362)
28、 SIGRTMAX-263) SIGRTMAX-164) SIGRTMAX非可靠信号一般都有确定的用途及含义, 可靠信号则可以让用户自定义使用 二 信号的安装 早期的Linux使用系统调用 signal 来安装信号#include <signal.h>void (*signal(int signum, void (*handler)(int)(int); 该函数有两个参数, signum指定要安装的信号, handler指定信号的处理函数.该函数的返回值是一个函数指针, 指向上次安装的handler经典安装方式:if (signal(SIG
29、INT, SIG_IGN) != SIG_IGN) signal(SIGINT, sig_handler);先获得上次的handler, 如果不是忽略信号, 就安装此信号的handler由于信号被交付后, 系统自动的重置handler为默认动作, 为了使信号在handler处理期间, 仍能对后继信号做出反应, 往往在handler的第一条语句再次调用 signalsig_handler(ing signum) /* 重新安装信号 */ signal(signum, sig_handler);
30、0; .我们知道在程序的任意执行点上, 信号随时可能发生, 如果信号在sig_handler重新安装信号之前产生, 这次信号就会执行默认动作, 而不是sig_handler. 这种问题是不可预料的.使用库函数 sigaction 来安装信号为了克服非可靠信号并同一SVR4和BSD之间的差异, 产生了 POSIX 信号安装方式, 使用sigaction安装信号的动作后, 该动作就一直保持, 直到另一次调用 sigaction建立另一个动作为止. 这就克服了古老的 signal 调用存在的问题#include <signal.h> int sigaction(in
31、t signum,const struct sigaction *act,struct sigaction *oldact);经典安装方式:struct sigaction action, old_action;/* 设置SIGINT */action.sa_handler = sig_handler;sigemptyset(&action.sa_mask);sigaddset(&action.sa_mask, SIGTERM);action.sa_flags = 0;/* 获取上次的handler, 如果不是忽略动作, 则安装信号 */sigaction(SIGINT, NU
32、LL, &old_action);if (old_action.sa_handler != SIG_IGN) sigaction(SIGINT, &action, NULL);基于 sigaction 实现的库函数: signalsigaction 自然强大, 但安装信号很繁琐, 目前linux中的signal()是通过sigation()函数实现的,因此,即使通过signal()安装的信号,在信号处理函数的结尾也不必再调用一次信号安装函数。 三 如何屏蔽信号 所谓屏蔽, 并不是禁止递送信号, 而是暂时阻塞信号的递送,&
33、#160;解除屏蔽后, 信号将被递送, 不会丢失. 相关API为int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset(sigset_t *set, int signum);int sigdelset(sigset_t *set, int signum);int sigismember(const sigset_t *set, int signum);int sigsuspend(const sigset_t *mask);int sigpending(sigset_t *set);-int
34、0;sigprocmask(int how, const sigset_t *set, sigset_t *oldset);sigprocmask()函数能够根据参数how来实现对信号集的操作,操作主要有三种:* SIG_BLOCK在进程当前阻塞信号集中添加set指向信号集中的信号* SIG_UNBLOCK如果进程阻塞信号集中包含set指向信号集中的信号,则解除 对该信号的阻塞* SIG_SETMASK更新进程阻塞信号集为set指向的信号集屏蔽整个进程的信号: C代码 1. #include <s
35、ignal.h> 2. #include <stdio.h> 3. #include <stdlib.h> 4. #include <error.h> 5. #include <string.h> 6. 7. void sig_handler(int signum) 8. 9. &
36、#160; printf("catch SIGINTn"); 10. 11. 12. int main(int argc, char *argv) 13. 14. sigset_t block; 15. struct sigaction
37、action, old_action; 16. 17. /* 安装信号 */ 18. action.sa_handler = sig_handler; 19. sigemptyset(&action.sa_mask); 20. ac
38、tion.sa_flags = 0; 21. 22. sigaction(SIGINT, NULL, &old_action); 23. if (old_action.sa_handler != SIG_IGN) 24.
39、sigaction(SIGINT, &action, NULL); 25. 26. 27. /* 屏蔽信号 */ 28. sigemptyset(&block); 29. sigaddset(&block, SIG
40、INT); 30. 31. printf("block SIGINTn"); 32. sigprocmask(SIG_BLOCK, &block, NULL); 33. 34. printf("-> send SIGINT ->
41、;n"); 35. kill(getpid(), SIGINT); 36. printf("-> send SIGINT ->n"); 37. kill(getpid(), SIGINT); 38. sleep(1);
42、 39. 40. /* 解除信号后, 之前触发的信号将被递送, 41. * 但SIGINT是非可靠信号, 只会递送一次 42. */ 43. printf("unblock SIGINTn"); 4
43、4. sigprocmask(SIG_UNBLOCK, &block, NULL); 45. 46. sleep(2); 47. 48. return 0; 49. #include <signal.h>#include <stdio.h>#incl
44、ude <stdlib.h>#include <error.h>#include <string.h>void sig_handler(int signum) printf("catch SIGINTn");int main(int argc, char *argv) sigset_t block; struct sigaction action, old_action; /* 安装信号 */ action.sa_handler = sig_handler; sigemptyset(&action.sa_mask); action
45、.sa_flags = 0; sigaction(SIGINT, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction(SIGINT, &action, NULL); /* 屏蔽信号 */ sigemptyset(&block); sigaddset(&block, SIGINT); printf("block SIGINTn"); sigprocmask(SIG_BLOCK, &block, NULL); printf("-> send
46、 SIGINT ->n"); kill(getpid(), SIGINT); printf("-> send SIGINT ->n"); kill(getpid(), SIGINT); sleep(1); /* 解除信号后, 之前触发的信号将被递送, * 但SIGINT是非可靠信号, 只会递送一次 */ printf("unblock SIGINTn"); sigprocmask(SIG_UNBLOCK, &block, NULL); sleep(2); return 0; 运行结果: C代码
47、160;1. work> ./a.out 2. block SIGINT 3. -> send SIGINT -> 4. -> send SIGINT -> 5. unblock SIGINT 6. catch SIGINT work> ./a.out block SIGINT-> send SIGIN
48、T ->-> send SIGINT ->unblock SIGINTcatch SIGINT这里发送了两次SIGINT信号 可以看到, 屏蔽掉SIGINT后, 信号无法递送, 解除屏蔽后, 才递送信号, 但只被递送一次,因为SIGINT是非可靠信号, 不支持排队.只在信号处理期间, 屏蔽其它信号在信号的handler执行期间, 系统将自动屏蔽此信号, 但如果还想屏蔽其它信号怎么办? 可以利用 struct sigaction 结构体的 sa_mask 属性. C代码 1. #include <signal.h>
49、60; 2. #include <stdio.h> 3. #include <stdlib.h> 4. #include <error.h> 5. #include <string.h> 6. 7. void sig_handler(int signum) 8. 9.
50、0;printf("in handle, SIGTERM is blockedn"); 10. /* 在此handler内将屏蔽掉SIGTERM, 直到此handler返回 */ 11. printf("-> send SIGTERM ->n"); 12.
51、 kill(getpid(), SIGTERM); 13. sleep(5); 14. printf("handle donen"); 15. 16. 17. void handle_term(int signum) 18. 19.
52、0; printf("catch sigterm and exit.n"); 20. exit(0); 21. 22. 23. int main(int argc, char *argv) 24. 25. struct sigaction
53、 action, old_action; 26. 27. /* 设置SIGINT */ 28. action.sa_handler = sig_handler; 29. sigemptyset(&action.sa_mask); 30.
54、0; /* 安装handler的时候, 设置在handler 31. * 执行期间, 屏蔽掉SIGTERM信号 */ 32. sigaddset(&action.sa_mask, SIGTERM); 33. action.sa_flags = 0; 34.
55、60; 35. sigaction(SIGINT, NULL, &old_action); 36. if (old_action.sa_handler != SIG_IGN) 37. sigaction(SIGINT, &action, NULL);
56、 38. 39. 40. /* 设置SIGTERM */ 41. action.sa_handler = handle_term; 42. sigemptyset(&action.sa_mask); 43.
57、; action.sa_flags = 0; 44. 45. sigaction(SIGTERM, NULL, &old_action); 46. if (old_action.sa_handler != SIG_IGN) 47.
58、160; sigaction(SIGTERM, &action, NULL); 48. 49. 50. printf("-> send SIGINT ->n"); 51. kill(getpid(), SIGINT);
59、160; 52. 53. while (1) 54. sleep(1); 55. 56. 57. return 0; 58. #include &l
60、t;signal.h>#include <stdio.h>#include <stdlib.h>#include <error.h>#include <string.h>void sig_handler(int signum) printf("in handle, SIGTERM is blockedn"); /* 在此handler内将屏蔽掉SIGTERM, 直到此handler返回 */ printf("-> send SIGTERM ->n"); kill(getpid(), SIG
61、TERM); sleep(5); printf("handle donen");void handle_term(int signum) printf("catch sigterm and exit.n"); exit(0);int main(int argc, char *argv) struct sigaction action, old_action; /* 设置SIGINT */ action.sa_handler = sig_handler; sigemptyset(&action.sa_mask); /* 安装handler的时候,
62、设置在handler * 执行期间, 屏蔽掉SIGTERM信号 */ sigaddset(&action.sa_mask, SIGTERM); action.sa_flags = 0; sigaction(SIGINT, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction(SIGINT, &action, NULL); /* 设置SIGTERM */ action.sa_handler = handle_term; sigemptyset(&action.sa_mask); ac
63、tion.sa_flags = 0; sigaction(SIGTERM, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction(SIGTERM, &action, NULL); printf("-> send SIGINT ->n"); kill(getpid(), SIGINT); while (1) sleep(1); return 0; 运行结果: C代码 1. work> ./a.out
64、0;2. -> send SIGINT -> 3. in handle, SIGTERM is blocked 4. -> send SIGTERM -> 5. handle done 6. catch sigterm and exit. work> ./a.out-> send SIGINT ->
65、in handle, SIGTERM is blocked-> send SIGTERM ->handle donecatch sigterm and exit. 收到SIGINT后, 进入sig_handler,此时发送SIGTERM信号将被屏蔽, 等sig_handler返回后, 才收到SIGTERM信号, 然后退出程序 四 如何获取未决信号所谓未决信号, 是指被阻塞的信号, 等待被递送的信号. int sigsuspend(const sigset_t *mask);sigpending(sigset_t *set)获得当
66、前已递送到进程,却被阻塞的所有信号,在set指向的信号集中返回结果。 C代码 1. #include <signal.h> 2. #include <stdio.h> 3. #include <stdlib.h> 4. #include <error.h> 5. #include <string.h> 6. 7. /*
67、160;版本1, 可靠信号将被递送多次 */ 8. /#define MYSIGNAL SIGRTMIN+5 9. /* 版本2, 不可靠信号只被递送一次 */ 10. #define MYSIGNAL SIGTERM 11. 12. void sig_handler(int signum) 13. 14.
68、160; psignal(signum, "catch a signal"); 15. 16. 17. int main(int argc, char *argv) 18. 19. sigset_t block, pending; 20.
69、 int sig, flag; 21. 22. /* 设置信号的handler */ 23. signal(MYSIGNAL, sig_handler); 24. 25. /* 屏蔽此信号 */ 26.
70、0; sigemptyset(&block); 27. sigaddset(&block, MYSIGNAL); 28. printf("block signaln"); 29. sigprocmask(SIG_BLOCK, &block, NULL); 30. &
71、#160; 31. /* 发两次信号, 看信号将会被触发多少次 */ 32. printf("-> send a signal ->n"); 33. kill(getpid(), MYSIGNAL); 34. pri
72、ntf("-> send a signal ->n"); 35. kill(getpid(), MYSIGNAL); 36. 37. /* 检查当前的未决信号 */ 38. flag = 0; 39. &
73、#160; sigpending(&pending); 40. for (sig = 1; sig < NSIG; sig+) 41. if (sigismember(&pending, sig) 42.
74、0; flag = 1; 43. psignal(sig, "this signal is pending"); 44.
75、160; 45. 46. if (flag = 0) 47. printf("no pending signaln"); 48. 49.
76、160; 50. /* 解除此信号的屏蔽, 未决信号将被递送 */ 51. printf("unblock signaln"); 52. sigprocmask(SIG_UNBLOCK, &block, NULL); 53. 54.
77、60; /* 再次检查未决信号 */ 55. flag = 0; 56. sigpending(&pending); 57. for (sig = 1; sig < NSIG; sig+) 58.
78、60; if (sigismember(&pending, sig) 59. flag = 1; 60. psignal(sig,
79、160;"a pending signal"); 61. 62. 63. if (flag = 0) 64. prin
80、tf("no pending signaln"); 65. 66. 67. return 0; 68. #include <signal.h>#include <stdio.h>#include <stdlib.h>#include <error.h>#include <str
81、ing.h>/* 版本1, 可靠信号将被递送多次 */#define MYSIGNAL SIGRTMIN+5/* 版本2, 不可靠信号只被递送一次 */#define MYSIGNAL SIGTERMvoid sig_handler(int signum) psignal(signum, "catch a signal");int main(int argc, char *argv) sigset_t block, pending; int sig, flag; /* 设置信号的handler */ signal(MYSIGNAL, sig_handler); /*
82、屏蔽此信号 */ sigemptyset(&block); sigaddset(&block, MYSIGNAL); printf("block signaln"); sigprocmask(SIG_BLOCK, &block, NULL); /* 发两次信号, 看信号将会被触发多少次 */ printf("-> send a signal ->n"); kill(getpid(), MYSIGNAL); printf("-> send a signal ->n"); kill(getpid(), MYSIGNAL); /* 检查当前的未决信号 */ flag = 0; sigpending(&pending); for (sig = 1; sig < NSIG; sig+) if (sigismember(&p
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【正版授权】 ISO 16179:2025 EN Footwear - Critical substances potentially present in footwear and footwear components - Determination of organotin compounds in footwear materials
- 湖南文理学院芙蓉学院《建筑材料学B》2023-2024学年第二学期期末试卷
- 中国计量大学《地方教学名师课堂》2023-2024学年第二学期期末试卷
- 抚顺职业技术学院《感觉统合训练》2023-2024学年第一学期期末试卷
- 河南医学高等专科学校《广告理论与实务》2023-2024学年第二学期期末试卷
- 古代描写英雄的诗句
- 公共交通车辆更新淘汰制度
- 第3课 “开元盛世”教案2024-2025学年七年级历史下册新课标
- 烟道伸缩节施工方案
- 2025年医药产业布局洞察:数据解析A股市场走势与板块表现
- 《慢性阻塞性肺病的》课件
- 2023年沈阳职业技术学院单招数学模拟试题附答案解析
- 《企业经营统计学》课程教学大纲
- 六年级下册道德与法治课件第一单元第三课
- 房地产合约规划分类明细
- 八年级物理(上册)知识点整理 (2)
- 高中物理万有引力定律知识点总结与典型例题
- 吊装平台施工方案
- 欧姆定律-中考复习课件
- 中学语文课程标准研究最新试题及答
- 如何激发学生学习物理的兴趣PPT课件
评论
0/150
提交评论