簡體   English   中英

C語言編程。 使用execl和pthread

[英]C programming. Using execl and pthread

我在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;
        }
...

和函數Start_Process_Thread:

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

        }
    }
}

上面的代碼從技術角度來看效果很好,但是我在處理被調用外部過程的不同實例的返回值時遇到了問題。 特別是,與某個實例相關聯的返回值隨機地歸屬於另一個實例。 例如,假設分別使用參數meas1,meas2,meas3和meas4調用了外部過程的4個不同實例,並假設成功處理了meas1,meas2和meas3,而對於meas4,則該過程失敗。 在這種情況下,我的代碼混合了返回值,從而使meas1,meas3和meas4成功,而meas2失敗,或者meas1,meas2,meas4成功,而meas3成功。

為什么會發生這種情況的任何想法?

任何幫助都非常歡迎。

預先感謝您的關注。

當某個進程中的任何線程執行wait() ,它將獲取有關該進程的任何死子的信息-不一定是有關正在等待的線程啟動的最后一個子信息。

您將需要考慮:

  1. 捕獲死進程的PID(它由wait()返回,但是您可以忽略它)。
  2. 將一個線程指定為“屍體處理者”(該線程除了wait()不執行任何操作,並記錄和報告子進程族中的死亡情況)。
  3. 一種數據結構,允許啟動進程的線程記錄其死亡時對子狀態的興趣。 據推測,一旦孩子開始,孩子應該在合適的條件下等待,這樣就不會浪費CPU時間,而無濟於事。
  4. 每當“屍體處理者”線程收集屍體時,它都會處理其他適當線程的通知。
  5. 擔心過程超時,並殺死野蠻時間過長的孩子。

有時候這是病態的生意...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM