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

销售网站后台维护怎么做网页制作与网站建设的发展趋势设想

销售网站后台维护怎么做,网页制作与网站建设的发展趋势设想,老年门户网站建设的意义,企业年金一般交多少钱前言 作者#xff1a;小蜗牛向前冲 名言#xff1a;我可以接受失败#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话#xff0c;还请点赞#xff0c;收藏#xff0c;关注#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、信号的保… 前言 作者小蜗牛向前冲 名言我可以接受失败但我不能接受放弃   如果觉的博主的文章还不错的话还请点赞收藏关注支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、信号的保存  1、信号其他相关常见概念 2、信号在内核中的表示 3、sigset_t 4. 信号集操作函数  二、 模仿实现内核对信号的保存 1、信号函数 2、实验代码 三、信号的的捕捉  1、内核态和用户态 2、信号的捕捉流程  四、信号的补充知识 1、sigaction函数 2、可重入函数 3、 volatile关键字 本期学习目标信号的保存信号的捕捉什么是可重入函数和关键字volatile。 一、信号的保存  1、信号其他相关常见概念 实际执行信号的处理动作称为信号递达(Delivery)信号从产生到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞 (Block )某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.注意: 阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。 2、信号在内核中的表示 信号在内核中的表示示意图 每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理动作。 从位图中我们理解pending位图和信号的关系 操作系统发信号本质也就是将信号写入到pending位图中。pending位图中的比特位的内容也就表征了是否收到该信号 对于block位图比特位的位置也是代表信号的编号但是比特位的内容表示是否阻塞对应的信号。如果阻塞了就不在执行该信号除非解除阻塞。  if((1(signo -1)) pcb-block) {//signo信号被阻塞不递达 } else {if((1(signo -1)) pcb-pending){//递达该信号} }上面我们写了一份伪代码来理解内核是如何大致处理信号未决到递达的过程和信号阻塞。 其中在内核中还有一个handler的数组用来存放信号其中数组的下标表示信号的编号数组 下标对应的内容表示信号的内容。 所以当一个信号没有产生这并不妨碍他可以先被阻塞。 3、sigset_t 从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。         因此,未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号 的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有 效”和“无效”的含义是该信号是否处于未决状态。      阻塞信号集也叫做当 前进程的信号屏蔽字(Signal Mask),这里的“屏蔽”应该理解为阻塞而不是忽略 4. 信号集操作函数  sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统 实现,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset_ t变量,而不应该对它的内部数据做 任何解释,比如用printf直接打印sigset_t变量是没有意义的 。 #include signal.h int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset (sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); int sigismemberconst sigset_t *set, int signo); 函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含 任何有 效信号。函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示 该信号集的有效信号包括系 统支持的所有信号。 注意在使用sigset_ t类型的变量之前,一定要调 用sigemptyset或sigfillset做初始化,使信号集处于确定的 状态。初始化sigset_t变量之后就可以在调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号 这四个函数都是成功返回0,出错返回-1。sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0,出错返回-1。  二、 模仿实现内核对信号的保存 为了更好的理解内核如何进行对信号的保存的下面我们自己写一份代码去验证信号在内核中的保存。 1、信号函数 sigprocmask函数 功能可以读取或更改进程的信号屏蔽字(阻塞信号集)。 原型int sigprocmask(int how, const sigset_t *set, sigset_t *oset) 返回值若成功则为0,若出错则为-1 如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则 更改进程的信号屏蔽字,参数how指示如何更改。果oset和set都是非空指针,则先将原来的信号 屏蔽字备份到oset里,然后 根据set和how参数更改信号屏蔽字。 上面一直说信号屏蔽字那这到底有上面用 信号屏蔽字是一个位掩码用于指定哪些信号被阻塞屏蔽而不会被递送给进程。当某个信号被屏蔽时它将被搁置直到信号解除屏蔽为止。这允许进程在关键部分屏蔽某些信号以确保在执行临界区代码时不会被中断。  对于sigprocmask函数当假设当前屏蔽字为mask 下表说明了how参数的可选值. SIG_BLOCKset包含了我们希望添加到当前信号屏蔽字的信号相当于maskmask|setSIG_UNBLOCKset包含了我们希望从当前信号屏蔽字中解除阻塞的信号相当于maskmask~setSIG_SETMASK设置当前信号屏蔽字为set所指向的值相当于maskse sigpending 函数 功能读取当前进程的未决信号集,通过set参数传出 原型int sigpending(sigset_t *set) 返回值调用成功则返回0,出错则返回-1。 2、实验代码 这里我们验证2号信号为例(ctrlc) #includeiostream #includevector #includesignal.h #includeunistd.h #includestdio.husing namespace std; #define MAX_SIGNUM 31static vectorint sigarr {2};static void show_pending(const sigset_t pending) {for(int signo MAX_SIGNUM; signo 1;signo--){if(sigismember(pending,signo)){cout 1;}else{cout 0;}}cout endl; }static void myhandler(int signo) {cout signo 号信号已经被递达!! endl; }int main() {for(const auto sig : sigarr) signal(sig, myhandler);sigset_t block, oblock, pending;//初始化sigemptyset(block);sigemptyset(oblock);sigemptyset(pending);//添加要屏蔽的信号for(const auto sig : sigarr) sigaddset(block,sig);//开始屏蔽设置内核sigprocmask(SIG_SETMASK,block,oblock);//遍历打印penging信号集int cnt 10;while(true){//初始化sigemptyset(pending);//获取sigpending(pending);//打印show_pending(pending);sleep(1);printf(%d\n,cnt);if(cnt-- 0){sigprocmask(SIG_SETMASK,oblock,block);cout 恢复对信号的屏蔽,不屏蔽任何信号endl;}}return 0; } 三、信号的的捕捉  1、内核态和用户态 在理解信号捕捉流程前我们要明白什么是内核态和用户态 内核态Kernel Mode 权限高 内核态拥有系统的最高权限可以执行特权指令和访问系统的所有资源。操作系统内核运行 在内核态下操作系统的内核代码运行可以执行对硬件的直接访问和控制。敏感指令 内核态可以执行一些敏感指令如修改全局页表、禁止中断等。特权级别 通常内核态运行在较高的特权级别Ring 0或Supervisor Mode这是计算机体系结构如x86中的一个常见术语。 用户态User Mode 权限低 用户态拥有较低的权限受到更多的限制无法直接访问底层硬件资源。用户应用程序运行 在用户态下用户应用程序运行其执行受到操作系统的控制和限制。受限指令 用户态下的程序不能直接执行一些特权指令如修改页表、禁止中断等。特权级别 用户态通常运行在较低的特权级别Ring 3或User Mode。 在正常的程序执行中处理器在用户态和内核态之间进行切换。当应用程序需要执行需要更高权限的操作时如访问硬件、执行特权指令会触发一个从用户态到内核态的切换。这通常通过系统调用system call来实现应用程序请求操作系统执行某些特权操作操作系统会在内核态执行相应的服务例程。  在进行切换身份进行系统调用的时候调用的人是进程但是身份是内核。系统调用是比较占用时间的所以我们应该尽量频繁的使用系统调用。 理解什么是内核态和用户态 那一个进程是怎么跑到OS中去执行方法的呢 这是因为每个进程都有自己的地址空间(用户独占的空间)内核空间(被映射到了每个进程的3~4G) 这时进程要访问OS的接口只要在自己的地址空间上跳转就好了 注意每个进程都会3~4GB地址空间都会共享一个内核级页表无论进程如何切换都吧会更该这个页表 2、信号的捕捉流程  其实上面的进程捕捉流程我们可以用倒写的8字来记忆 注意 默认情况下我们所以的信号是不被阻塞的默认情况下如果一个信号被屏蔽了该信号就不会被递达 四、信号的补充知识 1、sigaction函数 功能读取和修改与指定信号相关联的处理动作 原型 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) 参数 signum 是指定信号的编号若act指针非空,则根据act修改该信号的处理动作若oact指针非空,则通过oact传 出该信号原来的处理动作 返回调用成功则返回0,出错则返回- 1 act和oact指向sigaction结构体 : 将sa_handler赋值为常数SIG_IGN传给sigaction表示忽略信号,赋值为常数SIG_DFL表示执行系统默认动作,赋值为一个函数指针表示用自定义函数捕捉信号,或者说向内核注册了一个信号处理函数,该函数返回 值为void,可以带一个int参数,通过参数可以得知当前信号的编号,这样就可以用同一个函数处理多种信 号。显然,这也是一个回调函数,不是被main函数调用,而是被系统所调用 当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来 的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么 它会被阻塞到当前处理结束为止。 如果 在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需 要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。  下面我们通过代码来理解一下sigaction函数 #includeiostream #includecstdio #includesignal.h #includeunistd.husing namespace std;void Count(int cnt) {while(cnt){printf(cnt: %2d\r, cnt);fflush(stdout);cnt--;sleep(1);}printf(\n); }void handler(int signo) {cout get a signo: signo 正在处理中... endl;Count(20); } int main() {struct sigaction act, oact;act.sa_handler handler;act.sa_flags 0;sigemptyset(act.sa_mask); // 当我们正在处理某一种信号的时候我们也想顺便屏蔽其他信号就可以添加到这个sa_mask中sigaddset(act.sa_mask, 3);sigaction(SIGINT, act, oact);while(true) sleep(1);return 0; } 这里我们观察到我们一直给进程发2号信号发现他不马上执行所育的2号信号的而是一个一个的执行。 这里我们就知道了正在递达某个信号期间同类信号无法被递达系统会自动将当前信号加入到进程的信号屏蔽字block当信号完成捕捉动作系统又会自动解除对该信号的屏蔽(一般一个信号被解除屏蔽的时候会自动递达当前屏蔽信号如果该信号已经被pending的话就不做任何处理)。 2、可重入函数 为了理解可重写入函数这里我们有一个链表我们做如下操作 这里我们发现node2丢失了 我们代码也没有写错而仅仅是在一个mian函数中执行了二个执行流。 这里在mian函数handler中该函数重复进入 出了问题我们就称函数insert为不可以重入函数。 这里在mian函数handler中该函数重复进入 没有出问题我们就称函数insert为可以重入函数。 如果一个函数符合以下条件之一则是不可重入的 调用了malloc或free,因为malloc也是用全局链表来管理堆的。调用了标准I/O库函数。标准 比特科技 I/O库的很多实现都以不可重入的方式使用全局数据结构 3、 volatile关键字 下面我们看一个现象 int quit 0; void handler(int signo) {printf(pid: %d, %d 号信号正在被捕捉!\n, getpid(), signo);printf(quit: %d, quit);quit 1;printf(- %d\n, quit); }int main() {signal(2,handler);while(!quit);printf(我是正常退出\n); } 这个结果是显而易见。 当我们调整 gcc的优化程度可用man gcc手册查看 //调整优化gcc g -o $ $^ -O3 #-stdc11 在次运行代码  发现代码进入了死循环这是为什么呢 这是因为main函数中有二个流编译器认为在main执行流中quit没有改所以编译器只将物理内存中的值由0变1但是Cpu中寄存器中0没有变。编译器的优化 为了解决编译器的优化这就要用到volatile 关键字 volatile 作用保持内存的可见性告知编译器被该关键字修饰的变量不允许被优化对该变量的任何操作都必须在真实的内存中进行操作 volatile int quit 0; 在次运行代码问题就解决了
http://wiki.neutronadmin.com/news/138341/

相关文章:

  • 沈阳做网站价格网站平台建设什么意思
  • 装修网站cms长沙互联网推广公司
  • 企业标准网站模板wordpress主题背景图
  • 企业开展网站建设WordPress勾选评论
  • 装修第三方平台网站建设张雪峰不建议报的计算机
  • 网站域名哪些后缀更好做网站月收入
  • 电子商务网站订单功能用seo对网站做分析
  • 淘客软件自动做网站微信h5用什么软件制作
  • 爱南宁app下载官网中小学一键优化软件
  • 网站建设与管理是什么vue本地访问服务器跨域
  • 建设厅网站如何查询企业信息网国家免费技能培训有哪些
  • xx旅行社网站建设方案 企网站技术解决方案为申请虚拟主机开发公司个人工作总结
  • 建设一个网站引言优化大师最新版本
  • 南昌门户网站wordpress菜单项目边距和填充
  • 沈阳网站定制开发centos 7.2 wordpress
  • asp.net网站备份做购物商城网站
  • 咸阳网站开发公司地址量品定制
  • 沈阳网站提升排名平台建站
  • 网站开发盈利wordpress 最好的编辑器
  • cad做彩图那个网站应用好用织梦cms零基础做网站
  • dedecms做手机网站莱芜网站建设公众号建设
  • 上海平台网站建设费用免费设计logo图标生成器
  • 中国石油大学网页设计与网站建设塑胶包装东莞网站建设
  • 南京网站建设公司哪家好简易动漫网站模板
  • 宾馆酒店 网站模板网站建设服务哪家好
  • 网站建设实施过程物业公司管理系统
  • 免费软件站网站设计的国际专业流程包括
  • 网站营销活动div网站模板
  • 电脑网站打不开是什么原因造成的网站建设全网推广
  • 潍坊网站建设优化个人网站怎么维护