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

网站seo诊断湖南岚鸿诊断内部网站开发

网站seo诊断湖南岚鸿诊断,内部网站开发,西安千秋网络科技有限公司怎么样,网站建设自查情况本教程基于 Ubuntu 20.10 gcc 10.2.0. 示例程序如果不能正常编译和执行#xff0c;说明您系统和工具版本与我的不匹配#xff0c;请自行查阅资料。 0 概述 先给出该信号的描述#xff1a; SignalValueDescriptionSIGCHLD17Child status has changed (POSIX). Signal sent …本教程基于 Ubuntu 20.10 gcc 10.2.0. 示例程序如果不能正常编译和执行说明您系统和工具版本与我的不匹配请自行查阅资料。 0 概述 先给出该信号的描述 SignalValueDescriptionSIGCHLD17Child status has changed (POSIX). Signal sent to parent process whenever one of its child processes terminates or stops.See the YoLinux.com Fork, exec, wait, waitpid tutorial参考All signals in c/c 意思是说当父进程的多个子进程中某个子进程结束或停止的时候就会触发父进程的信号处理函数。 1 父进程与一个子进程 先看示例 #include stdio.h #include stdlib.h #include unistd.h #include sys/types.h #include signal.hpid_t pid 0;void sigchld_handler(int sig){printf(father call the SIGCHLD signal handler. num %d\n,sig); }int main(){signal(SIGCHLD,sigchld_handler);pid fork();if(pid -1){exit(1);} else if(pid 0){ // child codeprintf(child process is running, pid %d.\n,getpid()); } else { // father codepause();printf(father process runs again.\n);} return 0; }输出结果是 child process is running, pid 352252. father call the SIGCHLD signal handler. num 17 father process runs again.1.1 程序分析 我们先分析一下这个程序 一开始使用了signal函数并且设置了如果子进程结束则父进程的函数sigchld_handler会被触发执行。类似于“开中断” 父进程使用fork分出来一个子进程 子进程执行child code代码父进程执行father code代码二者是并发执行的 如果父进程执行结束之前子进程先结束执行了子进程会给父进程发送信号SIGCHLD那么父进程就会触发signal转而执行函数sigchld_handler执行完该函数后父进程继续执行后面的代码。 如果子进程发送信号的时候父进程已经执行结束了那么函数sigchld_handler也不会执行了因为父进程已经执行完了。 这里需要特别注意的是signal的本质是软中断也就是中断因此对于允许被信号SIGCHLD中断的父进程来说在触发之前父进程都是正常执行的就与硬中断是一样的 另外这里其实是更高抽象层次的软件中断与底层的软中断还不是一回事儿需要明确这一点。 此外尽管看起来这个中断是子进程发送给父进程的但是实际上是Linux操作系统发送给父进程的也就是说子进程其实先把信号给了OS。当然你可以先忽略这一点。因为……很多东西都要经过OS的控制的所以说一直关注这个也没必要。 1.2 程序框架 下面来说一下关于一个父进程和一个子进程的程序框架。 #include stdio.h #include stdlib.h #include unistd.h #include sys/types.h #include signal.hpid_t pid 0;void sigchld_handler(int sig){// 这里写处理函数 }int main(){signal(SIGCHLD,sigchld_handler);pid fork();if(pid -1){exit(1);} else if(pid 0){ // child code// 这里写子进程代码 } else { // father code// 这里写父进程代码} return 0; }然后分别说明一下。 首先是信号处理函数 void sigchld_handler(int sig){// 这里写处理函数 }对于函数名可以随意改其他的不能改函数参数只能是int类型参数名可以改返回值只能是void。内容随意写。 如果你想使用main函数中定义的参数只能将其设置为全局变量了。 参考Providing/passing argument to signal handler You can’t have data of your own passed to the signal handler as parameters. Instead you’ll have to store your parameters in global variables. (And be really, really careful if you ever need to change those data after installing the the signal handler). But why? Now I don’t know about it. 然后说说父进程的代码。 ... else { // father code// 这里写父进程代码 } ...需要注意的是我们前面说过如果子进程发送结束信号的时候父进程已经执行完了父进程就不会调用信号处理函数了因此我们需要设置一个东西保证子进程结束的时候父进程一定没有执行完当然你必须知道这只是出于教学目的让你看见父进程是会调用信号处理函数的。真实情况下完全没有必要等着。 所以说可以加什么呢理论来说其实加啥都行只要让父进程执行地慢一点就好了。 举例 else { // father codesleep(10);// 这里写父进程代码 } 下面我就只说明sleep(10)的位置可以替换什么。 1. pause(); 2. wait(NULL); 3. for循环99999999次 4. ...这些都可以不过其实使用pause()就好让程序暂停当触发信号服务函数之后暂停自然结束然后父进程就会执行信号处理函数再执行其他代码。 对于for循环99999999次是不推荐的因为执行完信号处理函数这个循环需要继续执行直到结束。而且数值太小了也没用要知道执行的很快再加上这样会占用CPU。 使用 wait(NULL); pause();是最好的父进程会被挂起等待子进程执行结束然后就执行信号处理函数再执行其他代码。不会出现多余的等待时间对比for循环。 sleep(n)也不会出现多余等待时间被打断后就没了不会打断完回来接着睡这个应该与内部实现有关但是睡眠的秒数是不确定的谁知道子进程执行多久呢因此不要采用这个。 最安全的是wait waitpid wait(...); waitpid(...);因为pause()是无条件等待这样一来如果在执行它之前子进程已经执行完并且调用了处理函数了之后再执行了pause那么父进程将陷入无限等待。 而wait就不一样了它能够识别子进程是否执行完了如果没执行就等着执行完了执行服务程序如果在此之前就执行完了那就不等了直接往下执行。(waitpid的option参数请使用产生阻塞的0)。 参考Wait System Call in C 但是有的时候pause也是很好用的这个就视情况而定吧看你自己了。 Use pause function to wait a signal arrivers. 1.3 默认的信号处理函数 对于信号SIGCHLD默认处理参数SIG_DFL就是忽略。另外默认的处理就相当于是系统提前安装好的处理方法你可以直接调用默认的也可以自定义之前我们就是自定义。 参考 [1] IBM documentation: signal: Install signal handler [2] signal(7) — Linux manual page 至于细节这里不说了内容比较多给出参考链接自己看看就好。 另外根据执行结果你可以看到信号处理函数参数sig的值是17也就是信号SIGCHLD的value. 2 父进程与两个子进程 要知道这个信号父进程可以被任意一个它的子进程打断那么如何识别和区分多个子进程的结束呢我们看示例程序 #include stdio.h #include stdlib.h #include unistd.h #include sys/types.h #include signal.h #include sys/wait.hpid_t fd1 0; pid_t fd2 0; int stat 0;int wd1 0; int wd2 0;void sigchld_handler(int sig){// represent if this function is called.printf(father call the SIGCHLD signal handler.\n);wd1 waitpid(fd1,stat,0);wd2 waitpid(fd2,stat,0);if(wd1 fd1){ // child1 finishprintf(child1 process has finished.\n);}if(wd2 fd2){ // child2 finishprintf(child2 process has finished.\n);} }int main(){signal(SIGCHLD,sigchld_handler);fd1 fork();if(fd1 -1){exit(1);} else if(fd1 0){ // child1 codeprintf(child process is running, pid %d.\n,getpid()); } else {fd2 fork();switch(fd2){case -1:exit(1);break;case 0:// child2 codeprintf(child process is running, pid %d.\n,getpid()); break;default: // father codepause();printf(father process runs again.\n);break;}} return 0; }对于示例程序执行结果可能有2种情况 child process is running, pid 375332. child process is running, pid 375333. father call the SIGCHLD signal handler. child1 process has finished. child2 process has finished. father call the SIGCHLD signal handler. father process runs again. 或者 child process is running, pid 375332. child process is running, pid 375333. father call the SIGCHLD signal handler. child1 process has finished. child2 process has finished. father process runs again. 少了1个father call the SIGCHLD signal handler.。 示例程序采用了一种粗暴的算法这种方式反而是最好用的一定能够捕获到两个子进程的结束。 首先pause暂停父进程如果2个子进程某一个结束就会触发父进程的信号处理函数然后该函数就等着直到2个子进程都结束才会继续执行相关处理操作此过程中并没有理会最初是哪个子进程的结束导致了触发。 因此来说后面的两个if语句一定会被执行。 此时需要知道只要有子进程结束就会发送信号让父进程调用信号处理程序因此总体来说发送的信号一定是2个而父进程一定会接收到第一个信号第二个信号就不一定了可能接收之前父进程就已经退出了就接收不到了。 所以才有了2种不同的输出结果差异也是由此导致的。 参考Signals Close Together Merge into One If multiple signals of the same type are delivered to your process before your signal handler has a chance to be invoked at all, the handler may only be invoked once, as if only a single signal had arrived. In effect, the signals merge into one. This situation can arise when the signal is blocked, or in a multiprocessing environment where the system is busy running some other processes while the signals are delivered. This means, for example, that you cannot reliably use a signal handler to count signals. The only distinction you can reliably make is whether at least one signal has arrived since a given time in the past. 根据GNU官方的说法多个相同类型的信号都被发送给一个进程的时候在调用handler之前这些信号可能会被合并也就是说handler可能仅仅执行一次。具体细节参考链接。 至于为什么第二次调用的时候if语句块不会执行那是因为一旦waitpid( , ,0)执行完成此时等待的进程就退出了你再第二次调用返回的一定是-1了肯定就不会执行。 最后需要知道父进程等待子进程结束再执行得根据实际需求来现在就纯粹是为了教学而已。 另外基于其中断的本质来说中断本来就是随机的父进程特意等待中断其实有点奇怪的不过有需求的话完全可以这样做。 图示说明刚才的程序 情况1 情况2 这个信号处理函数一定会被调用2次 不一定在父进程没有结束的前提下一定调用2次父进程结束的话可能调用1次或者0次因此最多被调用2次 但是一定会发送2次信号给父进程每个子进程结束的时候发送1次而父进程最多接收到2次 参考how a father process know which child process send the signal SIGCHLD You cannot reliably use a signal handler to count signals. 在调用handler之前不能保证父进程能够接收到多个相同类型的信号这是其自身机制导致的。因此你只能假设父进程只接收到了1次信号调用了1次hanlder然后去做相关的事情。 signal的作用范围和作用时效到底是什么多次调用会发生什么经过测试好像在开头调用1次就够了即便在handler内部再调用结果也一样似乎它是允许嵌套多次调用的暂时没有查阅相关资料。
http://www.pierceye.com/news/330051/

相关文章:

  • 做3个网站需要多大的服务器做地铁建设的公司网站
  • 深圳app网站建设哪家好广西桂林
  • 网站开发及上线过程网站建设备案策划书
  • 杭州九鸿科技网站开发网站模板 素材
  • 网站建设网站软件有哪些wordpress如何输入拼音
  • 昆山网站建设哪家便宜简单的模板网站
  • 做图标得英文网站wordpress写代码插件
  • 网站网页设计案例wordprees可以做棋类网站吗
  • 天河区门户网站官网小学生一分钟新闻播报
  • 漯河网站建设lhwzzz网络服务器机柜
  • 有口碑的武进网站建设国内做房车游网站
  • 山东省城乡住房和城乡建设厅网站济南网站建设wuliankj
  • 网站首页跳出弹窗wordpress远程后台设置
  • 免费信息网站建设平台影响网站排名的因素 权重
  • 做房产网站接不到电话湖北网站建设平台
  • 厦门国外网站建设公司排名上海自贸区注册公司优惠政策
  • 网站建设的公司实习做什么成都住建局官网住建智慧建管
  • 建一个免费看电影的网站犯法不国家企业信用信息没有网站怎么做
  • 长春网站vantage wordpress
  • 帝国cms如何做网站地图自己做的网站还要买域名么
  • 网站建设与维护税率网络营销案例及视频
  • 网站建设 繁体精品课网站制作
  • 常州 招网站开发seo的名词解释
  • 二级域名网站seo竞价网站建设
  • 麻栗坡网站建设正规网站建设
  • 邯郸网站建设哪家好重庆app开发
  • 自学网站开发多久大型网站建站
  • 网站设计定制多少钱新增备案网站负责人
  • 匿名聊天网站开发网站关键字挖掘
  • 外国域名注册很多网站做网站的人找不到了