Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言编程。使用execl和pthread_C_Pthreads - Fatal编程技术网

C语言编程。使用execl和pthread

C语言编程。使用execl和pthread,c,pthreads,C,Pthreads,我在结合使用execl()和pthread时遇到了一个问题 我的想法很简单:编写一个守护进程,在特定情况下启动一个外部进程(相对于守护进程本身是一个单独的可执行文件),然后等待该进程的返回值。此外,我希望能够同时启动同一流程的多个实例 我的代码中处理多个线程的部分: ... for (c_thread=0,i=0;i<N;i++) { /* Start actions before start threads */ for (j=c_thre

我在结合使用execl()和pthread时遇到了一个问题

我的想法很简单:编写一个守护进程,在特定情况下启动一个外部进程(相对于守护进程本身是一个单独的可执行文件),然后等待该进程的返回值。此外,我希望能够同时启动同一流程的多个实例

我的代码中处理多个线程的部分:

...
for (c_thread=0,i=0;i<N;i++)
        {
        /* Start actions before start threads */
        for (j=c_thread;j<c_thread+config.max_threads;j++)
                         Before_Process(act[act_index[j]].measID);

       /* Now create threads */
        for (c=0,j=c_thread;j<c_thread+config.max_threads;j++)
                {
                        Print_Log(LOG_DEBUG,"Create tread n. %d, measurementID=%s",c,act[act_index[j]].measID);
                        if ((ret=pthread_create(&pth[c],NULL,Start_Process_Thread,(void *) &act[act_index[j]].measID)))
                                {
                                        Print_Log(LOG_ERR,"Error in creating thread (errorcode: %d)",ret);
                                        exit(EXIT_FAILURE);
                                }
                c++;
                }
        /* Joint threads */
        for (j=0;j<config.max_threads;j++)
                {
                        if ((ret=pthread_join(pth[j], (void**) &r_value[j])))
                        {
                                Print_Log(LOG_ERR,"Error in joint thread (errorcode: %d)",ret);
                                exit(EXIT_FAILURE);
                        }
                }
       /* Perform actions after the thread */
        for (j=0;j<config.max_threads;j++)
                {
                        status=*(int*) r_value[j];
                        Print_Log(LOG_DEBUG,"Joint tread n. %d. Return value=%d",j,status);
                       After_Process(act[act_index[c_thread+j]].measID,status);

                }

        c_thread += config.max_threads;
        }
...
从技术角度来看,上面的代码工作得很好,但是我在处理被调用的外部进程的不同实例的返回值时遇到了问题。特别是,与某个实例关联的返回值随机地归属于另一个实例。 例如,假设使用参数meas1、meas2、meas3和meas4分别调用外部过程的4个不同实例,并假设meas1、meas2和meas3成功处理,而对于meas4,过程失败。在这种情况下,我的代码混淆了返回值,返回值表示meas1、meas3和meas4成功,返回值表示meas2失败,返回值表示meas1、meas2、meas4成功,返回值表示meas3失败

你知道为什么会这样吗

欢迎任何帮助


提前感谢您的关注。

当进程中的任何线程执行
wait()
时,它会获取有关该进程的任何死亡子进程的信息,而不一定是关于执行等待的线程启动的最后一个子进程的信息

您需要考虑:

  • 捕获已终止进程的PID(它由
    wait()
    返回,但您忽略它)
  • 有一个被指定为“尸体处置器”的线程(一个只做
    wait()
    和记录并报告子进程家族中的死亡的线程)
  • 一种数据结构,允许启动进程的线程记录它们对子进程死亡时的状态感兴趣。据推测,一旦孩子启动,孩子应该在合适的条件下等待,这样它就不会在做任何有用的事情时消耗CPU时间
  • 每当“尸体处置器”线程收集尸体时,它会处理相应其他线程的通知
  • 担心进程超时,以及杀害长时间狂奔的儿童

  • 有时这是一种病态的业务…

    当进程中的任何线程执行
    wait()
    时,它会获取有关该进程的任何死亡子进程的信息,而不一定是关于执行等待的线程启动的最后一个子进程的信息

    您需要考虑:

  • 捕获已终止进程的PID(它由
    wait()
    返回,但您忽略它)
  • 有一个被指定为“尸体处置器”的线程(一个只做
    wait()
    和记录并报告子进程家族中的死亡的线程)
  • 一种数据结构,允许启动进程的线程记录它们对子进程死亡时的状态感兴趣。据推测,一旦孩子启动,孩子应该在合适的条件下等待,这样它就不会在做任何有用的事情时消耗CPU时间
  • 每当“尸体处置器”线程收集尸体时,它会处理相应其他线程的通知
  • 担心进程超时,以及杀害长时间狂奔的儿童

  • 有时这是一件病态的事情…

    谢谢!我用waitpid()函数代替wait()解决了这个问题。谢谢!我用waitpid()函数代替wait()解决了这个问题。
    void *Start_Process_Thread(void *arg)
    {
    
    int *ret;
    char *measID;
    measID=(char*)arg;
    
    if (!(ret=malloc(sizeof(int))))
            {
            Print_Log(LOG_ERR, "allocation memory failed, code=%d (%s)",
                                  errno, strerror(errno) );
                          exit(EXIT_FAILURE);
            }
    
    *ret=Start_Process(measID);
    pthread_exit(ret);
    }
    
    
    int Start_Process(char *measID)
    {
    ...
      pipe(pfd);
      pid=fork();
      if (!pid)
        {
          signal(SIGALRM,Timeout);
          alarm(config.timeout_process);
          flag=0;
          /*
             Start the Process.
          */
              ret=execl(config.pre_processor,buff_list[TokCount-1],config.db_name,measID,(char *) 0);
          if (ret==-1)
            {
              alarm(0);
              flag=1;
              Print_Log(LOG_ERR,"Cannot run script %s, code=%d (%s)",config.process, errno, strerror(errno));
            }
          alarm(0);
          close(1);
          close(pfd[0]);
          dup2(pfd[1],1);
          write(1,&flag,sizeof(int));
        }
      else
        {
          wait(&status);
          close(pfd[1]);
          read(pfd[0],&flag,sizeof(int));
          close(pfd[0]);
          if (!flag)
            {
              if (WIFEXITED(status))
                {
                  if (!(return_value=WEXITSTATUS(status)))
                    {
                      /*
                         Process gives no errors.
                      */
                      Print_Log(LOG_INFO, "Processing of measurementID=%s ended succesfully!",measID);
                    }
                  else
                    {
                      /*
                         Process gives errors.
                      */
                      Print_Log(LOG_WARNING,"Processor failed for measurementID=%s, code=%d",measID, return_value);
                    }
                }
              else
                {
                  /*
                     Timeout for Process
                  */
                  Print_Log( LOG_WARNING,"Timeout occurred in  processing measurementID=%s",measID);
                  return_value=255;
                }
    
            }
        }
    }