关于信号量的一些使用
一.编写一些关于信号量的代码
1.用signal实现Sleep():
(1)代码:
# include<stdio.h>
# include<string.h>
# include<signal.h>
typedef void (*Handler)(int sig);
void MyHandler(int sig)
{
(void) sig;
return;
}
int MySleep(int second)
{
Handler old_handler=signal(SIGALRM,MyHandler);
alarm(second);
pause();
signal(SIGALRM,old_handler);
return;
}
int main()
{
printf("before sleep");
MySleep(3);
printf("after sleep");
}
(2)makefile中的代码:
(3)实现结果:
2.实现volatile
(1)代码:
(2)makefile中的代码:
(3)实现结果:
3.用sigsuspend重写MySleep
(1)代码:
(2)makefile中的代码:
(3)实现结果:
4.编写程序使其不会产生僵尸进程
(1)代码:
法1:
# include<stdio.h>
# include<string.h>
# include<signal.h>
typedef void (*Handler)(int sig);
void MyHandler(int sig)
{
(void) sig;
wait(NULL);
}
int main()
{
signal(SIGCHLD,MyHandler);
int ret=fork();
if(ret>0)
{
while(1){
printf("fatherworking\n");
sleep(3);
waitpid(-1,NULL,WNOHANG);
}
}else if(ret==0){
printf("sonworking\n");
sleep(1);
}
else{
printf("perroris\n");
}
}
法2:若出现多个子进程,同时撤销会出现问题(还剩很多进程不能被回收)(wait<进程数)
# include<stdio.h>
# include<string.h>
# include<signal.h>
typedef void (*Handler)(int sig);
void MyHandler(int sig)
{
(void) sig;
printf("I anMyHandler");
while(1){
intpid=waitpid(-1,NULL,WNOHANG);
if(pid<=0){
break;
}
printf("wait=%d\n",wait);
}
}
int main()
{
signal(SIGCHLD,MyHandler);
int i=0;
for(;i<20;++i){
int ret=fork();
if(ret>0)
{
while(1){
printf("fatherworking\n");
sleep(3);
waitpid(-1,NULL,WNOHANG);
}
}else if(ret==0){
printf("sonworking %d\n",getpid());
sleep(1);
exit(0);
}
else{
printf("perroris\n");
}
}
法3:
int main()
{
signal(SIGCHLD,SIG_IGN);
int i=0;
for(;i<20;++i){
int ret=fork();
if(ret>0)
{
while(1){
printf("fatherworking\n");
sleep(3);
waitpid(-1,NULL,WNOHANG);
}
}else if(ret==0){
printf("sonworking %d\n",getpid());
sleep(1);
exit(0);
}
else{
printf("perroris\n");
}
}
二.一些总结:
1.pause函数使调用进程挂起直到有信号递达。
2.对于程序中存在多个执行流程访问同一全局变量的情况,volatile限定符是必要的,此外,虽然程序只有单一的执行流程,但是变量属于以下情况的,也需要volatile限定:(1)变量的内存单元中的数据不需要写操作就可以自己发生变化,每次读上来的值都可能不一样;(2)即使多次访问变量的内存单元中写数据,只写不读,也并不是在做无用功,而是有特殊意义的。