У меня странная проблема.основной процесс -> pthread -> fork + execvp
Иногда, когда я запускаю свою программу достаточно долго, я вижу, что есть две копии моей программы. Второй - дочерний процесс первого, так как я вижу, что родительский PID второй - это первый из них.
Я понял, что у меня есть вилка в моем коде, и только из-за этого у меня могут быть две копии - у меня никогда не может быть двух копий моей программы.
Это происходит очень редко, но это происходит.
архитектура выглядит следующим образом:
Основная программа получает событие и порождает PTHREAD. В этом потоке я делаю некоторую обработку и основываясь на некотором результате, я делаю вилку, за которой сразу следует execvp.
Я понимаю, что его не лучше назвать вилкой из pthread, но в моем дизайне основной процесс получает много событий, и единственным способом параллельной работы над всеми этими событиями было использование pthreads. Каждый pthread выполняет некоторую обработку, и в некоторых случаях ему нужно вызвать другую программу (для которой я использую execvp). Так как я должен был вызвать другую программу, мне пришлось использовать fork
Мне интересно, потому что я в конечном итоге вызываю вилку из контекста нити, возможно, что несколько потоков параллельны вызовам fork + execvp, и это «как-то» приводит к создаются две копии.
Если это действительно произойдет, это поможет, если я защищу код, который делает fork + execvp с помощью мьютекса, поскольку это приведет к тому, что только один поток вызовет fork + execvp.
Однако, если я возьму мьютекс перед fork + excvp, тогда я не знаю, когда его отпустить.
Любая помощь здесь будет оценена.
кодпоток, который делает вилку + execvp - в случае, если вы, ребята, можете обнаружить проблему там:
В main.c
status = pthread_create(&worker_thread, tattr,
do_some_useful_work, some_pointer);
[обрезанный]
void *do_some_useful_work (void * arg)
{
/* Do some processing and fill pArguments array */
child_pid = fork();
if (child_pid == 0)
{
char *temp_log_file;
temp_log_file = (void *) malloc (strlen(FORK_LOG_FILE_LOCATION) +
strlen("/logfile.") + 8);
sprintf (temp_log_file, "%s/logfile.%d%c", FORK_LOG_FILE_LOCATION, getpid(),'\0');
/* Open log file */
int log = creat(temp_log_file, 0777);
/* Redirect stdout to log file */
close(1);
dup(log);
/* Redirect stderr to log file */
close(2);
dup(log);
syslog(LOG_ERR, "Opening up log file %s\n", temp_log_file);
free (temp_log_file);
close (server_sockets_that_parent_is_listening_on);
execvp ("jazzy_program", pArguments);
}
pthread_exit (NULL);
return NULL;
}
Я смотрел через этот код, и я не вижу причин, почему я буду делать вилку, а не execvp, поэтому единственный сценарий, который приходит мне на ум, заключается в том, что несколько потоков выполняются, и все они вызывают fork + execvp. Это иногда приводит к запуску двух копий моей основной программы.
Код, который вы предоставили, недостаточен для диагностики или воспроизведения проблемы, о которой вы просите, но я ответил некоторыми идеями. –