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

岫岩做网站公司推广哪个平台好

岫岩做网站,公司推广哪个平台好,高端网站开发哪家专业,wordpress如何本地安装插件fork创建子进程 在Linux系统中&#xff0c;使用fork创建子进程&#xff0c;是简单方便地进行多进程开发的方法。 fork的原型如下&#xff1a; #include <unistd.h> pid_t fork(void);fork被调用以后&#xff0c;会有三种返回值。 0&#xff0c;表示子进程创建成功&am…

fork创建子进程

在Linux系统中,使用fork创建子进程,是简单方便地进行多进程开发的方法。

fork的原型如下:

#include <unistd.h>  pid_t fork(void);

fork被调用以后,会有三种返回值。

  1. 0,表示子进程创建成功,当前进程在子进程中。返回值为子进程的pid。

  2. == 0,表示子进程创建成功,当前进程在父进程中。返回值为0。
  3. < 0,表示子进程创建失败。

如:

int 
main(int argc, char *argv[])
{pid_t ret;if ((ret = fork ()) == 0)  {  printf ("now in parent process !\n");  }  else if (ret > 0)  {  printf ("now in child process, pid is: %d !\n", ret);}  else  { printf("fork() error: %s\n", strerror (errno));  return -1;}return 0;
}

signal注册信号处理函数

在Linux中,可以给一个进程发送信号。

进程收到信号以后,则会执行程序注册的信号处理函数。

可以使用kill命令加-s [SIGNAL NAME] [pid]给一个进程发送信号。如果没有-s参数,则会发送默认地SIGINT信号。

默认地,程序收到SIGINT信号之后,会退出执行。但是我们可以实现自己的信号处理函数,改变这个默认行为。

注册信号处理函数的函数为signal,它的原型为:

#include <signal.h>  typedef void (*sighandler_t)(int);  sighandler_t signal(int signum, sighandler_t handler);

可以看到,signal的使用只需要一个信号值和一个回调函数的参数。非常直观,就是什么信号要执行什么函数。

信号值为SIG开头的一系列值,可以通过kill -L命令列表查看。

回调函数为sighandler_t,即void sighandler(int)的形式。

比如,我们可以简单地注册一个处理SIGINT的函数:

#include <signal.h>static void
int_han(int sig) 
{// 注意这里仅为示例所用,实际开发中,应该避免在信号处理函数中执行这类函数。下面详细说明。printf("received sigint signal !\n");
}int
main (int argc, char *argv[])
{signal (SIGINT, int_han);sleep (60);return 0;
}

信号处理函数注意事项

信号处理函数可能在很多极端条件下被调用,如:

  • 在另一个信号处理函数执行过程中
  • 在 malloc/free 等内存分配函数执行过程中
  • 在标准 I/O 函数执行过程中在信号处理函数中。

所以信号处理过程中不能调用非异步信号安全(async-signal-safe)的函数。

不能调用的常见函数包括:

  • 标准IO,如printf、scanf等
  • 内存分配释放,如malloc、free等
  • system、exit、abort等

更好的实践是,在信号处理函数中只设置值,之后快速返回。

sigaction的使用

在较新的代码中,已经不推荐使用signal,而是使用sigaction了。

因为signal是老接口,功能相对简单。而sigaction 是POSIX标准,提供更完整的信号处理控制。

如:

  • signal 在信号处理函数执行时,会临时将信号处理方式重置为默认行为。而sigaction可以指定 SA_RESTART标志,使被信号中断的系统调用自动重启。
  • signal不能设置信号屏蔽字,而sigaction可以通过sa_mask 设置信号屏蔽字,防止信号处理函数被其他信号中断。
  • 在回调函数的执行中,signal只能得到信号的编号,而sigaction可以通过siginfo_t获取更多信号相关的信息,甚至可以通过最后一个context参数,获取到程序运行相关的信息,比如程序堆栈等。

sigaction的原型为:

#include <signal.h>struct sigaction {  void     (*sa_handler)(int);  void     (*sa_sigaction)(int, siginfo_t *, void *);  sigset_t   sa_mask;  int        sa_flags;  void     (*sa_restorer)(void);  
};int sigaction(int signum,  const struct sigaction *_Nullable restrict act,  struct sigaction *_Nullable restrict oldact);

以上的signal实现,替换为sigaction则为:

static void
int_han(int signo, siginfo_t *info, void *context) 
{printf("received sigint signal !\n");
}int
main (int argc, char *argv[])
{struct sigaction sa;sa.sa_sigaction = sig_han;sa.sa_flags = SA_SIGINFO | SA_RESTART;sigemptyset(&sa.sa_mask);sigaction(SIGINT, &sa, NULL);sleep(60);return 0;
}

随父进程退出

当fork执行成功以后,子进程会清零PR_SET_PDEATHSIG,以至于父进程退出以后,子进程也不关心。

但是,如果我们希望父进程退出的时候,子进程也一并退出,可以使用prctl函数,注册一个父进程中止时的信号。

prctl (PR_SET_PDEATHSIG, SIGTERM);// 或者
prctl (PR_SET_PDEATHSIG, SIGKILL);

监控子进程退出

当子进程退出的时候,会向父进程发送SIGCHLD信号。

父进程可以通过这个信号,使用wait取得子进程的退出状态。

如:

void 
sig_child (int sig) 
{int status;  pid_t pid;  // 循环读取到至今所有的子进程退出事件while ((pid = waitpid (0, &status, WNOHANG)) > 0)  {if (WIFEXITED (status))  printf ("child process: %d exit with %d\n", pid, WEXITSTATUS (status));else if (WIFSIGNALED (status))  ldebug ("child process: %d killed by the %dth signal\n", pid, WTERMSIG (status));}
}int 
main (int argc, char *argv[])
{signal (SIGCHLD, sig_child);
}

信号的屏蔽

屏蔽信号,可以使用sigprocmask

sigprocmask的原型为:

int sigprocmask(int how, const sigset_t *_Nullable restrict set,  sigset_t *_Nullable restrict oldset);

其中,how的可选值为SIG_BLOCK或者SIG_UNBLOCK,set与oldset都是sigset_t结构体。

操作sigset_t的函数有:

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);

分别表示置空、所有、添加、删除以及是否包含。

如以下调用将屏蔽所有信号:

sigset_t mask;sigfillset(&mask);
sigprocmask(SIG_BLOCK, &mask, NULL);

还可以使用SIG_UNBLOCK随时恢复:

sigset_t mask;
sigfillset(&mask);
sigprocmask(SIG_UNBLOCK, &mask, NULL);

但是,更建议使用pthread提供的pthread_sigmask函数,因为sigprocmask在多线程条件下行为未定义,但是pthread_sigmask是线程安全的。

另外,pthread_sigmask只影响当前线程。

fork的回调

pthread还实现了fork的回调函数注册机制pthread_atfork,可以在创建子进程的之前、之后,执行自定义的函数。

pthread_atfork的原型为:

#include <pthread.h>  int pthread_atfork(void (*prepare)(void), void (*parent)(void),
void (*child)(void));

其中,prepare是fork之前执行的回调函数,parent是fork之后父进程执行的函数,child是fork之后子进程执行的函数。

比如以下代码,实现了在fork之前屏蔽掉信号处理,fork之后再恢复,避免在fork过程中因为信号处理而出现异常。

// fork之前,屏蔽掉SIGHUP信号
void 
pre_fork() 
{sigset_t mask;sigemptyset(&mask);sigaddset(&mask, SIGHUP);pthread_sigmask(SIG_BLOCK, &mask, NULL);
}// fork之后,父进程打开SIGHUP信号
void 
post_fork_parent() 
{sigset_t mask;sigemptyset(&mask);sigaddset(&mask, SIGHUP);pthread_sigmask(SIG_UNBLOCK, &mask, NULL);
}void post_fork_child() 
{// 子进程不使用SIGHUP信号
}// 在程序初始化时注册fork处理函数
int
main(int argc, char *argv[])
{pthread_atfork(pre_fork, post_fork_parent, post_fork_child);
}
http://www.dtcms.com/wzjs/835062.html

相关文章:

  • 营销型网站建设需要备案吗大约多少钱
  • 小地方的旅游网站怎么做网站备案要邮寄资料吗
  • 用wordpress建立电商网站游戏源码网站免费
  • 吐鲁番网站建设如何制作app软件下载
  • 网站开发 方案 报价单谷歌sem
  • 个人域名免费网站淘宝客做网站怎么做
  • 南充城市建设投诉网站定制logo
  • 美工网站设计收费做网站费用会计分录怎么做
  • 网站可以多个域名吗wordpress 死链检测
  • 招聘网站开发视频wordpress发不了文章
  • 企业建设好一个网站后_如何进行网站推广?睿思设计
  • 网站建设ppt模板芜湖市建设办网站
  • 那个网站上有打码的任务做wordpress文章归档调用
  • 承德工程建设信息网站自助网站免费注册
  • 网站留言模板做照片软件
  • 临沂建网站公司做电商网站都需要学什么条件
  • 做网站公司有什么出路企业简介怎么写
  • 专业下载网站源码网站流量突然暴增
  • 中国建设银行网站怎么交学费wordpress集成关注公众和登陆
  • 合肥 电子商务 网站建设沈阳网站制作公司思路
  • 东莞市五金有限公司 寮步 技术支持 网站建设wordpress discuz论坛
  • 都有什么网站域名信息备案管理系统官网
  • 建站哪家好论坛公众号开发工具
  • 微信微网站怎么进入万网虚拟主机免费空间
  • 青岛外贸建设网站查询网站服务器地址
  • 深圳 建设工程招标有限公司网站wordpress和drupal
  • 做盗号网站网站域名怎么买
  • 2 如何写一份详细的网站开发方案太原网站制作建设
  • 王者荣耀网站建设的步骤厦门seo优
  • 深圳网站工作室网络营销岗位招聘信息