简体   繁体   English

C ++和$之间的PID一致性! bash变量

[英]PID consistency between c++ and $! variable in bash

BEGIN BACKGROUND INFO 开始背景信息

I have a program in C++ that is inherently serial, and takes between 10 seconds to 30 minutes to run depending on the characteristics of the model I pass in. I have automated running the program with bash. 我有一个C ++程序,它本质上是串行的,并且运行10到30分钟不等,具体取决于传入模型的特性。我已经使用bash自动运行了该程序。 Deep in the C++ code, I am writing out some metrics to a file, but I can't access the name of the model. 在C ++代码的深处,我正在将一些指标写到文件中,但无法访问模型的名称。 So I had been writing to the same file with bash after running the C++ function. 因此,运行C ++函数后,我一直在用bash写入同一文件。 My bash file was as follows: 我的bash文件如下:

#!bin/bash
for i in *.run; do
  bash $i
  echo $i >> output.txt
done

This resulted in an output file essentially in this format: 这导致输出文件基本上采用以下格式:

metrics for model #1 written by C++
name for model #1 written by bash
metrics for model #2 written by C++
name for model #2 written by bash
etc...

With some 300 models, this took 12 hours to run, but knowing it was serial, I tried to run multiple instances of my C++ program in the background with this bash file 在大约300个模型中,这需要12个小时才能运行,但是知道它是串行的,所以我尝试使用此bash文件在后台运行C ++程序的多个实例

#!bin/bash
run_my_program()
{
  bash $1
  echo $1 >> output.txt
}

for i in *.run; do
  while [`jobs | wc -l` -ge 8 ]; do
    sleep 5
  done
  run_my_program $i &
done

This cut my execution time down to around 2 hours, however it destroyed the structure of my output file, making it hard to identify which metrics were attached to which file. 这将我的执行时间减少到大约2个小时,但是却破坏了我的输出文件的结构,从而使您很难确定将哪些指标附加到了该文件。

metrics for model #1 written by C++
name for model #1 written by bash
metrics for model # ?? written by C++
metrics for model # ?? written by C++
name for model #2 written by bash
name for model #3 written by bash
etc...

END BACKGROUND INFO 结束背景信息

So I'm trying to use intermediate files for each model, based on the process id, then concatenating the temp files into the main one. 因此,我尝试根据进程ID对每个模型使用中间文件,然后将临时文件连接到主要文件中。

#!bin/bash
run_my_program()
{
  bash $1 &
  myId=$!
  myFile="Temp_$myId.txt"
  wait $myId
  echo $1 >> $myFile
  cat $myFile >> output.txt
}

for i in *.run; do
  while [`jobs | wc -l` -ge 8 ]; do
    sleep 5
  done
  run_my_program $i &
done

My C++ code that opens the temp file for writing is as follows 我的用于打开临时文件进行写入的C ++代码如下

pid_t myprocess = getpid();
char tmpStr[10];
sprintf(tmpStr,"%d",myprocess);
std::string filename = "Temp_" + std::string(tmpStr) + ".txt";
fout.open(filename.c_str(),std::fstream::out | std::fstream::app);

Unfortunately the numbers in myprocess from C++ and myId from bash just aren't matching up. 不幸的是在数字myprocess从C ++和myId的庆典就是不匹配了。

QUESTION : Is there something I'm missing about how $! 问题 :关于$!我缺少什么$! and getpid() work that's giving me inconsistent numbers? getpid()工作给了我不一致的数字? Am I doomed to run my models in serial? 我注定要串行运行模型吗?

After

bash $1 &

$! is the pid of the bash child process. 是bash子进程的pid。 Presumably, $1 (something.run) is a script which ends up running the C++ program as a child, but that child process will be yet another pid. 大概$1 (something.run)是一个脚本,该脚本最终作为一个子代运行C ++程序,但是该子代进程将是另一个pid。

You might be able to modify your .run file to exec the C++ program instead of spawning a child, but that will only work if you don't need to do anything in the .run file afterwards. 您可能可以修改.run文件以exec C ++程序,而不用生成一个子进程,但这仅在以后不需要在.run文件中执行任何操作的情况下才有效。

Another relatively simple solution is to generate a subprocess count in your driver loop, and pass it through the .run file to the C++ program, which can then use it as a tag in log messages. 另一个相对简单的解决方案是在驱动程序循环中生成子进程计数,并将其通过.run文件传递给C ++程序,然后C ++程序可以将其用作日志消息中的标记。 That has the advantage of allowing the log messages to come from various different programs, if that is useful. 这样做的好处是,如果有用,则允许日志消息来自各种不同的程序。

Yet another simple solution is to output all logging information from your C++ program to stderr . 另一个简单的解决方案是将所有C ++程序的日志记录信息输出到stderr Then the .run script which actually calls the program can redirect stderr to a log file created using $$ -- the pid of the .run script -- which will be the same as $! 然后,实际调用程序的.run脚本可以将stderr重定向到使用$$创建的日志文件- $$ .run脚本的.run$!相同$! in the driver. 在驱动程序中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM