免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: flyhu
打印 上一主题 下一主题

!!并发守护进程的问题(急)!! [复制链接]

论坛徽章:
0
21 [报告]
发表于 2007-08-25 14:45 |只看该作者
原帖由 ivhb 于 2007-8-25 13:42 发表
while (i--)
{
    fetch 你的任务配置表
   if (SQLCODE == SQLNOTFOUND)  // all tasks activated
       break;
。。。。。。  
           if (pid == 0)
                {
                      ...


第一步,没有任务,就直接退出,未产生任何的子进程。

那第二步,wait还能够等待进程结束吗?前面没有产生任何的子进程。

我是想一直保持一定的进程数(如5个)在运行。

论坛徽章:
0
22 [报告]
发表于 2007-08-25 14:47 |只看该作者
原帖由 flyhu 于 2007-8-25 14:22 发表


用信号,是不是子进程也能收到?都是同样的处理方式?如何区分?

能够给一个信号处理示例吗?十分感谢。。我的程序框架都出来,多谢你。


用信号的话,父进程与子进程的PID不一样,是向你指定的那个PID的进程发送那个信号.写了个信号处理的比较简单的例子,你看看:

  1. #include<signal.h>
  2. #include<stdlib.h>
  3. #include<stdio.h>

  4. void sig_fun(int signo)
  5. {
  6.         printf("in sig_fun:pid=%d\n", getpid());
  7. }

  8. int main()
  9. {
  10.         pid_t pid;

  11.         struct sigaction act, oact;

  12.         act.sa_handler = sig_fun;
  13.         sigemptyset(&act.sa_mask);
  14.         act.sa_flags = 0;
  15.         act.sa_flags |= SA_INTERRUPT;
  16.         if (sigaction(SIGUSR1, &act, &oact) < 0)
  17.         {
  18.                 printf("sigaction error\n");
  19.         }

  20.         if ((pid = fork()) < 0)
  21.         {
  22.                 printf("fork error\n");
  23.                 exit(1);
  24.         }

  25.         if (pid == 0)
  26.         {
  27.                 while (1)
  28.                 {
  29.                         printf("in child, pid=%d\n", getpid());
  30.                         sleep(1);
  31.                 }
  32.         }
  33.         while (1)
  34.         {
  35.                 printf("in parent, pid=%d\n", getpid());
  36.                 sleep(1);
  37.         }

  38.         printf("done\n");
  39.         return 0;
  40. }
复制代码


你运行之后,就会打印出父,子进程各自的进程号,假如为1000, 1001. 然后你在另外一个终端输入命令:

kill -USR1 1000
或者是
kill -USR2 1001
就可以看到父子进程各自运行其信号处理程序.

论坛徽章:
0
23 [报告]
发表于 2007-08-25 14:49 |只看该作者
原帖由 flyhu 于 2007-8-25 14:45 发表


第一步,没有任务,就直接退出,未产生任何的子进程。

那第二步,wait还能够等待进程结束吗?前面没有产生任何的子进程。

我是想一直保持一定的进程数(如5个)在运行。



第一步,没有成功就退出的话,应该是退出了整个程序,那么也就不会执行后面的wait操作了.

论坛徽章:
0
24 [报告]
发表于 2007-08-25 15:25 |只看该作者
use pthread

论坛徽章:
0
25 [报告]
发表于 2007-08-25 16:47 |只看该作者

我的程序,嵌入oracle后无法产生守护进程,大家帮看看。。

*/
#include <sys/wait.h>
#include <signal.h>
#include <sys/resource.h>
#include <fcntl.h>
#include "nsi_srv.h"

#define PROCNAME "nsi_srv_batch"
#define printusage() \
                printf("   Usage:%s [-d num|-k] [-h]\n",PROCNAME);    \
                printf("         -d num以守护方式启动服务,num最大进程数,最小和缺省为4,最大不能超过99\n");    \
                printf("         -k 停止服务\n");    \
                printf("         -h 显示帮助\n");    \
                printf("         -d与-k不能同时出现\n");    \
                printf("   EXAMP:1. %s -d\n", PROCNAME);    \
                printf("         2. %s -k\n", PROCNAME);    \
                printf("         3. %s -h\n", PROCNAME);

#define errexit(aerrtxt) \
                elog(6,"%s", aerrtxt);    \
                dbrollback();    \
                dbclose();    \
                exit(EXIT_FAIL);

EXEC SQL INCLUDE SQLCA;

EXEC SQL BEGIN DECLARE SECTION;
    typedef struct{
        char jyr[8+1];                    /*服务交易日*/
        char stepid[6+1];            /*步骤号*/
        char srvid[18+1];                /*服务编号*/
    } Stru_StepDef;
EXEC SQL END DECLARE SECTION;

pid_t mpid;
int imaxp=4;
int iwaitfechs=600;  /*数据库取数据等待秒数*/
int iwaitforks=60;     /*fork错误等待秒数*/
int imaxforkerrs=10; /*最大fork尝试次数*/

void vfun(int i)
{
         pid_t subpid;
         
         subpid=getpid();
     elog(6,"[NB98]subpid=[%s]第[%d]个虚拟子进程产生成功!!cmd=[%s]",subpid,i);
     sleep(100);
}

void subp(const char *jyr, const char *stepid)
{               
                char cmd[256];
                pid_t subpid;
                int iret=0;
               
                subpid=getpid();
                memset((char *)cmd, 0x00, sizeof(cmd));
                    
                sprintf(cmd,"echo %d > %s/log/errlog/%d.pid", subpid,(char *)getenv("HOME"),subpid);
          iret=system(cmd);
          sleep(5);
          if (iret!=0)
          {
                  elog(6,"[NB99]subpid=[%s]运行子作业失败!!cmd=[%s]",subpid,cmd);
          }
          else
          {
                  elog(6,"[NB99]subpid=[%s]运行子作业成功!!cmd=[%s]",subpid,cmd);
          }
        //exit(0);

}


int daemon_init(void)
{
      pid_t pid;
      struct sigaction sa;
      struct rlimit r1;
      int i;
      
      elog(6,"sigaction begin!!");
      if ((pid = fork()) < 0)
              return -1;
      else if (pid != 0)
              exit(0);
      if (setsid() < 0)
              exit(1);
            elog(6,"sigaction 1!!");
      sa.sa_handler = SIG_IGN;
      sigemptyset(&sa.sa_mask);
      sa.sa_flags = 0;
      if (sigaction(SIGHUP, &sa, NULL) < 0)
      {
              //printf("sigaction error\n");

              elog(6,"sigaction error");
              exit(1);
      }
      elog(6,"sigaction 2!!");
      if ((pid = fork()) < 0)
              return -1;
      else if (pid != 0)
              exit(0);

      if (chdir("/") < 0)
              return -1;
      elog(6,"sigaction 3!!");
      
      umask(0);
      if (getrlimit(RLIMIT_NOFILE, &r1) < 0)
      {
               //printf("get file limit error\n");

               elog(6,"get file limit error");
               exit(1);
      }
      elog(6,"sigaction 4!!");
      if (r1.rlim_max == RLIM_INFINITY)
               r1.rlim_max = 1024;
      for(i = 0; i < r1.rlim_max; i++)
               close(i);
      elog(6,"sigaction 5!!");
      elog(6,"pid=[%d]!!",getpid()); ---这里可以取到进程号!!!!
      return 0;
}

论坛徽章:
0
26 [报告]
发表于 2007-08-25 16:47 |只看该作者
接上面......

int mainp()
{
    EXEC SQL BEGIN DECLARE SECTION;
          Stru_StepDef str_step;
    EXEC SQL END DECLARE SECTION;
   
    pid_t pid,ipid1;
  int i=5,iforkerrs=0;
  int n;
  long j = 0;
  
    /*启动守护进程*/
    n = daemon_init();
    elog(6,"daemon_init[%d]!!",n); ---这个有返回!!!!
  if (n != 0)
  {
      elog(6,"[NB03]后台服务守护进程启动..失败!!rtn=%d",n);
      exit(1);
  }
  
  /*取得父进程的pid号*/
  ipid1=getpid();   ----取不出来!!!!
  mpid=ipid1;
  
  elog(6,"mpid=[%s]!!",mpid);
  elog(6,"[NB03]mpid=[%s]后台服务守护进程启动...成功!!",mpid);

   
//imaxp=5;

    i=imaxp;
  while (i--)
  {
          iforkerrs=0;
         
          if ((pid = fork()) < 0)
      {
          iforkerrs++;
        elog(6,"[NB04]mpid=[%s]子进程产生失败,进行第[%d]次尝试!!",mpid,iforkerrs);
                exit(1);
      }
      if (pid == 0)
      {
              vfun(imaxp-i-1); /*虚拟子进程,初始化为5个*/
              exit(0);
      }
    }
   
  elog(6,"%s!!", "初始化5个成功!!");
  
  if (0!=dbconnect())
  {
    elog(6,"[NB01]连接数据库...失败!!sqlcode=%d",SQLCODE);
    exit(EXIT_FAIL);
  }
  
  elog(6,"[NB01]连接数据库...成功!!");
  
    EXEC SQL DECLARE cur_step CURSOR FOR
                     SELECT jyr, stepid, srvid
                     FROM nsi_srv_parall
                     WHERE isdone='0' AND isvalid='0' ORDER BY jyr,stepid;
   
    EXEC SQL OPEN cur_step;
    if( SQLCODE !=0 )
  {
      elog(6,"[NB02]服务类型作业配置表游标打开...失败!!sqlcode=%d",SQLCODE);
      
//Batch_Err(sprocname, scurjyr, s_errtxt);

      EXEC SQL CLOSE cur_step;
      dbdisconnect();
            exit(EXIT_FAIL);
  }
   
    elog(6,"[NB02]服务类型作业配置表游标打开...成功!!");
  
  j = 0;
  while (wait(NULL) > 0)
  {
          /*从作业表中取作业,如果没有作业则等待*/
          while (1)
          {   
                  memset((Stru_StepDef *)&str_step, 0x00, sizeof(Stru_StepDef));
                    EXEC SQL FETCH cur_step into :str_step;
                    if (NODATA) /*没有数据则循环等待10分钟*/
                    {
                            elog(6,"[NB05]mpid=[%s]没有作业需要运行,等待[%d]秒!!",mpid,iwaitfechs);
                            sleep(600);
                            continue;
                    }
                    if(SQLCODE!=0 && SQLCODE!=1405 && SQLCODE!=1403)
                    {
                        elog(6,"[NP05]mpid=[%s]从服务类型作业表中取数据...失败,退出!!sqlcode=%d",mpid,SQLCODE);
                        
//Batch_Err(sprocname, scurjyr, s_errtxt);

                            sleep(600);
                            continue;
                           
//errexit(s_errtxt);

                    }
                    break;
            }
            elog(6,"[NB05]mpid=[%s]从服务作业表中取数据...成功!!jry=[%s],stepid=[%s],srvid=[%s]", \
                                                mpid,str_step.jyr,str_step.stepid,str_step.srvid);
         
          /*产生子进程*/
          iforkerrs=0;
         
//while(1)

         
//{

                if ((pid = fork()) < 0)
                {
                  iforkerrs++;
                  elog(6,"[NB06]mpid=[%s]子进程产生失败,进行第[%d]次尝试!!",mpid,iforkerrs);
                  
//if (iforkerrs>imaxforkerrs);

                  
//{

                  
//        sprintf(s_errtxt,"[NB06]mpid=[%s]产生子进程失败,尝试超过[%s]次...退出!!",mpid,imaxforkerrs);

                              
//Batch_Err(sprocname, scurjyr, s_errtxt);

                                 EXEC SQL CLOSE cur_step;
                                 dbdisconnect();
                                    exit(1);
                 
// }

                  /*等待再尝试*/
                  
//sleep(iwaitforks);

                  
//continue;

                }
               
//break;

         
// }

        
        if (pid == 0) /*子进程*/
        {               
                  j++;
                  elog(6,"[NB06]mpid=[%s]产生总第[%ld]个子进程进行作业处理!!",mpid,j);
          subp((char *)str_step.jyr,(char *)str_step.stepid);
          exit(0);
        }
  }
  EXEC SQL CLOSE cur_step;
  dbdisconnect();
  return 0;
}


程序运行产生的log如下:
16:30:56->sigaction begin!!
16:30:56->sigaction 1!!
16:30:56->sigaction 2!!
16:30:56->sigaction 3!!
16:30:56->sigaction 4!!
16:30:56->sigaction 5!!
16:30:56->pid=[5906]!!
16:30:56->daemon_init[0]!!

目前程序执行到daemon_init();
处并没有产生后台进程,随后的getpid()无法取得父进程号,后面的子进程也都没产生。

我加pro*c部分前是可以的,请各位大侠帮助看看,顺便帮我看看我的代码,还有那些问题。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP