I am trying to execute multiple applications with fork() and execve(). and some of them has a dependency to each other. So for example, I want to make it execute A, B, C at the same time and make it wait until B is in "Running" status before execute C when the scenario is like below.
applications
A
B-C (C depends on B)
D
at the very first time. I came up with very primitive solution like below. fork and execute app and wait until its status changed to running state. (the application has Initial state and everything are ready it sends message that it is on the running status to state_mgr)
// app_starter.cpp
CreateAppProcess(...) {
...
child = fork();
...
if (child == 0) {
execve(name, argv, argc);
...
}
...
}
StartApplication(AppInstance& app) {
...
CreateAppProcess(app->name, app->argv, app->argc);
...
}
Use the function "StartApplication()" in this way.
//app_starter.cpp
// 1. declare AppInstance array.
AppInstance app_array[10];
// 2. set AppInstances in the array.
...
// 3. start apps
for (int i = 0 ; i < 10; i++) {
StartApplication(app_array[i]);
}
// 4. wait until "execve"d app is on Running state.
for (int i = 0; i < 1000000000; i++)
{
return_value = app_ins.GetAppState(app->name);
if(return_value == State::Running) break;
}
The solution above has a three problems.
So I am trying to fix problems one by one but I stuck at the very first soulution for 3. - condition_variable.
// app_instance.cpp
std::condition_variable g_app_cv;
std::mutex g_app_cv_mtx;
...
ReceiveAppStateMsg() {
while(_quit) {
ret_ = mq_receive(rcv_handler, buffer, size_, 0);
...
if (msg_rcvd == State::Running) {
...
g_app_cv.notify_one();
}
}
}
//app_starter.cpp
extern std::condition_variable g_app_cv;
extern std::mutex g_app_cv_mtx;
// 1. declare AppInstance array.
AppInstance app_array[10];
// 2. set AppInstances in the array.
...
// 3. start apps - change for loop to condition_variable.
for (int i = 0 ; i < 10; i++) {
StartApplication(app_array[i]);
}
// 4. wait until "execve"d app is on Running state.
{
std::unique_lock<std::mutex> lk(g_app_cv_mtx);
g_app_cv.wait_for(lk, std::chrono::milliseconds(1000));
}
in conclusion I need some insights about...
How to use condition_variable across the multiple cpp files.
The right way fork() and exec() with std::condition_variable.
How to fork() and exec() in simultaneously or with not much delay.
execution order timeline I want
start --- |end
--------------
A----|
B----|C----|
D----|
--------------
Thank you for read this long question.
You need to allocated the mutex as well as the condition variable in a shared memory region between the processes. You also need to set the attribute of your mutex and cond vars to be PTHREAD_PROCESS_SHARED
Howto Share memory: link
However, for the purpose similar to yours, i would prefer to write a small process life cycle module (built entirely on top of IPC using domain sockets ). You can divide the life cycle of your process into : INIT, RUNNING, ALIVE, STOPPED, DEAD ( based on what you wanna do, i am just giving you clues ). As soon as as your process reaches a stage in it's lifecycle you can publish out an event notifying the same. The other process can just sit block waiting for that state to be realized in the co-operating process. A simple heart beat mechanism can determine whether the other process is ALIVE or dead. The other stages can be notified via publishing out over IPC ( preferable domain sockets )