Я создал (а) простой класс Process
, который имитирует std::thread
. Предполагается, что он работает только с Linux.Waitpid и вопросы синхронизации
struct Process
{
Process(/*...*/) { /* fork + join, initialize m_pid */ }
~Process() { assert(!joinable()); }
bool joinable() const { return m_pid != 0; }
void join()
{
assert (joinable());
int status;
waitpid(m_pid, &status, 0);
m_pid = 0;
}
private:
std::atomic<pid_t> m_pid;
};
У меня есть дополнительное требование: мне нужно иметь возможность остановить процесс из другого потока.
Например:
Process p(/* ... */);
Thread 1:
p.join();
Thread 2:
p.interrupt();
Как я могу осуществить поточно-Process:interrupt
? Моя первая мысль что-то вроде этого:
void Process::interrupt()
{
if (m_pid)
kill(m_pid, SIGTERM);
}
К сожалению, я не уверен, что это работает, потому что если interrupt
называется между waitpid
и m_pid = 0
в join()
тогда я убивающий несуществующий процесс, или хуже, совершенно не связаны процесс, который имеет тот же самый pid, что и старый.
Перестановка заявления m_pid = 0
и waitpid
в join()
бы сделать перерыв совершенно бесполезно, так как вы можете ожидать, что первая нить будет проводить большую часть своего времени в ожидании завершения дочернего процесса.
Так что мне нужен waitpid
, который ждет завершения процесса дочернего процесса, но сохраняет дочерний процесс в состоянии зомби, так что ни один процесс с одним и тем же pid не может появиться в то же время.
Есть ли такая вещь или любое другое решение?
Вы можете просто использовать блокировку – Dani
@ Дани err ... как? Если я заблокирую весь раздел 'waitpid' +' m_pid = 0', тогда прерывание будет ждать завершения процесса. Это не то, что я хочу. В идеале мне нужно что-то вроде 'pthread_cond_wait', где вы можете передать блокировку функции, и она будет атомарно заблокирована при возврате' waitpid'. – sbabbi
Вы можете прервать waitpid, убить процесс и возобновить waitpid – Dani