gpt4 book ai didi

C编程。使用 execl 和 pthread

转载 作者:太空宇宙 更新时间:2023-11-04 07:33:12 24 4
gpt4 key购买 nike

我在结合使用 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;
}

}
}
}

从技术角度来看,上面的代码工作正常,但我在处理被调用外部进程的不同实例的返回值时遇到了问题。特别是,与某个实例关联的返回值会随机归因于另一个实例。例如,假设调用了 4 个不同的外部进程实例,参数分别为 meas1、meas2、meas3 和 meas4,并假设 meas1、meas2 和 meas3 已成功处理,而 meas4 进程失败。在这种情况下,我的代码混合了返回值,meas1、meas3 和 meas4 成功,meas2 失败,或者 meas1、meas2、meas4 成功,meas3 失败。

知道为什么会发生这种情况吗?

非常欢迎任何帮助。

预先感谢您的关注。

最佳答案

当进程中的任何线程执行 wait() 时,它会获得关于进程的任何已死亡子进程的信息——不一定是关于正在等待的线程启动的最后一个子进程的信息。

你需要考虑:

  1. 捕获死亡进程的 PID(它由 wait() 返回,但您忽略它)。
  2. 将一个线程指定为“尸体处理者”(该线程只执行 wait() 并记录和报告子进程系列中的死亡事件)。
  3. 一种数据结构,允许启动进程的线程记录他们对子进程死亡时的状态感兴趣。据推测,一旦 child 开始, child 应该等待合适的条件,这样它就不会消耗 CPU 时间做无用的事情。
  4. “尸体处理程序”线程在收集尸体时处理相应其他线程的通知。
  5. 担心进程超时,以及杀死跑得太久的 child 。

有时这是一件病态的事情......

关于C编程。使用 execl 和 pthread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11471797/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com