当前位置: 首页 > news >正文

学生组织网站建设做网站开发的提成多少钱

学生组织网站建设,做网站开发的提成多少钱,南京城乡建设网站,北京十大装饰公司排名有哪些目录 一,信号内核表示 sigset_t sigprocmask sigpending 二,捕捉信号 sigaction 三,可重入函数 四,volatile 五,SIGCHLD 信号常见概念 实际执行信号的处理动作,称为信号递达Delivery;信…

目录

一,信号内核表示

sigset_t

sigprocmask

sigpending

二,捕捉信号

sigaction

三,可重入函数

四,volatile

五,SIGCHLD


信号常见概念

  • 实际执行信号的处理动作,称为信号递达Delivery;
  • 信号从产生到递达的状态,称为信号未决Pending;
  • 进程可选择阻塞某个信号;
  • 被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才会执行递达动作;
  • 阻塞和忽略是不同的,信号被阻塞就不会递达,忽略是递达后可选的一种处理动作;

一,信号内核表示

  • 每个信号都有两个标志:阻塞、未决,及一个函数指针表示的动作;信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志;
    • SIGHUP信号,未产生也未阻塞,如递达时将执行默认动作;
    • SIGINT信号,产生过但被阻塞,暂时不能递达,处理动作为忽略;
    • SIGQUIT信号,未产生,如产生将被阻塞,处理动作为用户自定义函数;如该信号在阻塞前产生多次,POSIX允许系统递送该信号一次或多次,Linux常规信号在递达前产生多次只计一次,而实时信号在递达前产生多次可依次放在一个队列内;

sigset_t

  • 每个信号只有一个bit的未决标志,0或1,不记录该信号产生的次数;阻塞标志也是如此;
  • 未决和阻塞标志可用相同的数据类型sigset_t来存储,sigset_t称为信号集;该类型可表示每个信号的有效或无效;
//信号集操作函数
//在使用sigset_t类型的变量之前,一定要调用sigempty或sigfillset初始化,以使信号集处于确定状态;
//初始化后,即可调用sigaddset和sigdelset在信号集中添加或删除某种有效信号;
#include <signal.h>
int sigemptyset(sigset_t* set) //初始化信号集,使所有信号对应bit清零,表示该信号集不包含任何有效信号;
int sigfillset(sigset_t* set) //初始化信号集,使所有信号对应bit清零,表示该信号集的有效信号;
int sigaddset(sigset_t* set, int signo)
int sigdelset(sigset_t* set, int signo)
int sigismember(const sigset_t* set, int signo)

sigprocmask

  • 此函数可读取或更改进程的信号屏蔽字(阻塞信号集);
#include <signal.h>
int sigprocmask(int how, const sigset_t* set, sigset_t* oset);
  • 如oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出;
  • 如set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改;
  • 如oset和set都是非空指针,则先将原来的信号屏蔽字备份到oset,然后根据set和how更改信号屏蔽字;
  • 如当前信号屏蔽字为mask,则下表说明了how参数的可选值;

  • 如调用此函数解除了对当前若干个未决信号的阻塞,则在sigprocmask返回前,至少将其中一个信号递达;

sigpending

  • 检测未决信号;
#include <signal.h>
int sigpending(sigset_t* set)
#include <iostream>    
#include <signal.h>    
#include <unistd.h>    
using namespace std;    void show_pending(sigset_t* pending){    for(int i=1; i<32; i++){    if(sigismember(pending, i))    cout<<"1";    else    cout<<"0";    }    cout<<endl;    
}    int main()    
{    sigset_t in, out;    sigemptyset(&in);    sigemptyset(&out);    sigaddset(&in, 2);    sigprocmask(SIG_SETMASK, &in, &out);    int count=0;    sigset_t pending;    while(1){    sigpending(&pending);    show_pending(&pending);    sleep(1);    if(count==10){    sigprocmask(SIG_SETMASK, &out, &in); //恢复2号信号后, 2信号立即递达并执行默认操作  cout<<"my: ";    show_pending(&in);    cout<<"recover default: ";    show_pending(&out);    }    count++;                                                                                                 }    return 0;    
} 
[wz@192 Desktop]$ g++ test.cpp -o test
[wz@192 Desktop]$ ./test 
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
^C0100000000000000000000000000000
0100000000000000000000000000000
0100000000000000000000000000000
0100000000000000000000000000000
0100000000000000000000000000000
0100000000000000000000000000000
0100000000000000000000000000000
0100000000000000000000000000000

二,捕捉信号

        如信号的处理动作是用户自定义函数,在信号递达时就调用该函数,称为捕捉信号;由于信号处理函数的代码在用户空间,处理过程比较复杂;如,用户程序注册了SIGQUIT信号的处理函数sighandler,当前正在执行main函数,此时发生中断或异常,切换达到内核态;在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达;内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函数,sighandler和main函数使用不同的堆栈空间,不存在调用和被调用的关系,是两个独立的控制流程;sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态;如没有新的信号递达,再返回用户态就是恢复main函数的上下文继续执行;

sigaction

        当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时,如这种信号再次产生,那么会被阻塞到当前处理结束为止;

        如在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字; 

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
using namespace std;void handler(int signo){cout<<"get a signo: "<<signo<<endl;exit(10);
}int main(){struct sigaction act, oact;act.sa_handler = handler;act.sa_flags = 0;sigemptyset(&act.sa_mask);//act.sa_restorer = nullptr;//act.sa_sigaction = nullptr;sigaction(SIGINT, &act, &oact);while(1){cout<<"running..."<<endl;sleep(1);}return 0;
}

用户态,内核态;用户态需通过系统调用来访问内核数据,调用系统调用时系统会自动切换 身份;CPU会存在一个权限相关的寄存器数据,标识所处状态;每个用户进程都有自己的用户级页表,而OS只有一份内核页表;由于用户态和内核态的权限级别不同,所能看到的资源也是不一样的;

实时信号,不会丢失,会排队执行;

三,可重入函数

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
using namespace std;void show(int signo){int i=0;while(i<5){cout<<"show(), signo: "<<signo<<endl;i++;sleep(1);}
}void handler(int signo){cout<<"handler calling..."<<endl;show(signo);
}int main(){struct sigaction act, oact;act.sa_handler = handler;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaction(SIGINT, &act, &oact);show(999);return 0;
}
[wz@192 Desktop]$ ./test
show(), signo: 999
show(), signo: 999
show(), signo: 999
^Chandler calling...
show(), signo: 2
show(), signo: 2
show(), signo: 2
show(), signo: 2
show(), signo: 2
show(), signo: 999
show(), signo: 999

        像以上,insert插入函数被不同控制流调用,可能在第一次调用还没返回时,就再次进入该函数,称为重入;insert函数访问一个全局链表,有可能因为插入而造成错乱,像这样的函数称为不可重入函数;反之,如一函数只访问自己的局部变量或参数,称为可重入函数;所学的大部分函数都是不可重入的;

如函数符合以下条件之一,则是不可重入:

  • 调用了malloc或free,因malloc也是也是用全局链表来管理堆的;
  • 调用了标准I/O函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构;

四,volatile

        C语言关键字,保持内存的可见性;

#include <stdio.h>
#include <signal.h>int flag=0;
void handler(int signo){flag=1;printf("handler calling, get signo: %d\n", signo);
}int main(){signal(2, handler);while(!flag); //注意没有循环体printf("process quit normal!\n");return 0;
}
[wz@192 Desktop]$ gcc -o test test.c 
[wz@192 Desktop]$ ./test
^Chandler calling, get signo: 2
process quit normal!
//优化级别1
[wz@192 Desktop]$ gcc -o test test.c -O1
[wz@192 Desktop]$ ./test
^Chandler calling, get signo: 2
^Chandler calling, get signo: 2
^Chandler calling, get signo: 2

        优化后,flag被放在了CPU的寄存器当中,while循环的flag并不是内存中的最新flag;使用volatile关键字修饰变量后,则该变量不允许在被优化,对该该变量的任何操作都必须在真实的内存中进行;

#include <stdio.h>
#include <signal.h>volatile int flag=0;
void handler(int signo){flag=1;printf("handler calling, get signo: %d\n", signo);
}int main(){signal(2, handler);while(!flag); //注意没有循环体printf("process quit normal!\n");return 0;
}
[wz@192 Desktop]$ gcc -o test test.c -O1
[wz@192 Desktop]$ ./test
^Chandler calling, get signo: 2
process quit normal!

五,SIGCHLD

        SIGCHLD是第17号信号;进程wait、waitpid函数清理僵死进程,父进程可阻塞等待子进程结束,也可非阻塞查询是否有子进程结束等待清理(轮询);第一种方式父进程阻塞了,就不能处理自己的工作,第二种方式父进程在处理自己的工作同时还要记得轮询,程序实现复杂;

        其实,子进程在终止时会给父进程发送SIGCHLD信号,该信号默认处理动作为忽略,父进程可自定义SIGCHLD信号的处理函数;这样父进程只需专心处理自己的工作,不必关心子进程;子进程终止时通知父进程,父进程在信号处理函数中调用wait清理子进程即可;

        由于UNIX的历史原因,要想不产生僵死进程,还可在父进程调用sigaction时将SIGCHLD处理动作置为SIG_IGN,这样fork出来的子进程在终止时会自动清理,不会产生僵死进程,也不会通知父进程;系统默认的忽略动作和用户用sigaction函数自定义的忽略,通常是没有区别的,但这是特例;此方法对于Linux可用,但不保证在其他UNIX系统上都可使用;

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>void handler(int signo){printf("father get signo: %d\n", signo);pid_t id;//可能有多个子进程while((id=waitpid(-1,NULL,WNOHANG))>0){printf("wait child success: %d\n", id);}printf("child is quit! %d\n", getpid());
}int main(){signal(SIGCHLD, handler);pid_t cid;if((cid=fork()) == 0){printf("child: %d\n", getpid());sleep(3);exit(1);}while(1){printf("father process...!\n");sleep(1); //可以提前被唤醒}return 0;
}
[wz@192 Desktop]$ gcc -o test test.c
[wz@192 Desktop]$ ./test
father process...!
child: 99919
father process...!
father process...!
father get signo: 17
wait child success: 99919
child is quit! 99918
father process...!
father process...!
father process...!
father process...!

如不设置signal,子进程终止时,就会产生僵死进程;

如设置为SIG_IGN,子进程终止时,自动清理;

//如设置为忽略,fork出来的子进程在终止时会自动清理,不会产生僵死进程
signal(SIGCHLD, SIG_IGN);

        等待子进程,避免Z进程内存泄露,可能需获取子进程的退出码;父进程不关心子进程退出码,可不wait,如关心退出码必须wait;

http://www.yayakq.cn/news/681528/

相关文章:

  • 营销网站建设与推广方案做资源下载网站好吗
  • 东莞材料网站建设wordpress用户登录后
  • 双语网站建设网站建设的实验的结论
  • 冷色调网站wordpress模板媒体
  • 文山做网站yunling88运城网站制作路90
  • 杭州公司注销网站备案视频网站建设解决方案
  • 手机网站 广告郑州seo使用教程
  • 北京建站报价软件 开发公司
  • 怎么把在微企点做响应式网站中国建筑英才网官网
  • 网站开发怎么接单房地网站制作
  • 江苏省网站建设哪家好平台网站做数据维护需要多久
  • 梁山做网站价格微信h5页面制作免费
  • 家居企业网站建设策划做实体店优惠券的网站
  • 上海短视频seo优化网站软文推广的好处
  • 河南网站建设电话漳州网站建设多少钱
  • ps怎么做网站的广告条jsp项目个人网站开发
  • 良乡网站建设营销策划经典案例
  • 网站备案客户资料手机版网站开发html5
  • 小学学校网站模板免费下载中国十大保险经纪公司排名
  • 网站开发用技术wordpress被百度搜到
  • 阿里巴巴的关联网站国外云服务器厂商
  • 专业餐饮网站建设wordpress 识别二维码
  • 网站制作哪家便宜建立网站的软件下载
  • 湖北网站建设哪家好网站建设預算
  • 最好的网站建设推广学做小程序需要哪些基础
  • 网站制作设计发展前景温州网站建设wmwl
  • 微网站建设使用程序巢湖网站建设电话
  • 惠州手机网站商城建设狮山建网站
  • 广州icp网站测评无代码开发平台的利与弊
  • 帝国cms小说网站模板下载地址南宁市建设处网站