LINUX.ORG.RU

Си, fork() и глобальные переменные

 , ,


1

2

Хочу впилить в свой сишный код уже готовый фрагмент кода и запустить его в другом процессе.
Код определяет и использует свои глобальные переменные, нигде кроме как в этом коде они не используются.
Это безопасно?



Последнее исправление: ocr (всего исправлений: 1)

Ваще, с этим fork связаны некоторые ранние ошибки, допущенные при проектировании POSIX. Со временем набили шишки, и сейчас примерно понятно, что можно делать, а что нельзя в дочернем процессе. Обычно безопасно что-то прочитать с каналов, а затем загрузить новый образ в дочерний процесс. Все остальное надо рассматривать под очень большой увеличительной лупой, потому что код должен быть безопасен относительно сигналов. Есть очень ограниченный список функций, которые можно безопасно вызывать.

Например, если ты в дочернем процессе использовал мьютекс сразу после форка до загрузки образа, то в общем, все, считай, что твой код никуда не годится. А любой printf - это обращение к мьютексу. И тому подобное.

dave ★★★★★
()
Ответ на: комментарий от dave

а такой общий вариант вариант:


void any_func() {

pid_t pid;

//этот массив создается на стеке
char any_str_param[MAX_LEN_CHEGO_TO_TAM];
strcpy(any_str_param, "param_value");


//тут дитя
if(!pid) {

  ececl(
    BINPATH_STR,
    BINNAME,
    char any_str_param, //массив на стеке от родителя
    NULL
  );

}

return;

}
BINNAME может содержать любой код, даже мьютексы и пайпы. По идее, образ процесса-дитя замещается новым образом BINNAME. Должно быть так что массив созданный на стеке будет иметь копию в порожденном процессе и его адрес передастся в execl. Затем где-то в недрах execl скопируется весь массив как строка и только тогда будет загружен новый образ процесса.

Поправьте меня пожалуйста

ocr
() автор топика
Ответ на: комментарий от dave

Например, если ты в дочернем процессе использовал мьютекс сразу после форка до загрузки образа, то в общем, все, считай, что твой код никуда не годится.

Это вы с кодом внутри обработчиков сигналов попутали. После fork() в дочернем процессе использовать мьютексы можно и безопасно (если вы, конечно, не пытаетесь делать что-то типа разблокировки мьютекса, заблокированного перед форком родительским процессом).

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

После fork() в дочернем процессе использовать мьютексы можно и безопасно (если вы, конечно, не пытаетесь делать что-то типа разблокировки мьютекса, заблокированного перед форком родительским процессом).

Ты точно ничего не напутал сам? Безопасно только после загрузки через execv (и подобные) в новом образе. Пока образ не загружен - опасно.

У меня был наглядный пример, когда серверный софт регулярно падал под нагрузкой из-за этой хрени. Как поправили, то стало работать как часы.

dave ★★★★★
()
Ответ на: комментарий от ocr

После execl может делать, что хочешь. Главное, между fork и execl быть очень осторожным! Только я не понял, как ты собрался передать данные через execl. Читай лучше документацию и меньше советуйся на ЛОРе.

dave ★★★★★
()
Ответ на: комментарий от dave

Да, точно. Это вообще общепринятая практика в реализации серверов, состоящих из нескольких процессов. Да и вообще иначе и нельзя сделать многопроцессный сервер, кроме как делая fork(), но _не_ делая exec.

Sorcerer ★★★★★
()
Ответ на: комментарий от dave

даннеы в execl передаются как локальные массивы созданные в родителе. Локальные переменные ведь должны иметь копии в процессе-потомке?

ocr
() автор топика
Ответ на: комментарий от ocr

Сразу после fork - да, но обращение к ним не всегда безопасно, а вот после безопасного exec(*) - уже нет никаких данных. Если бы было все так просто, то fork давно бы перетащили во все языки программирования! Поэтому нужно продумать, как передавать данные. А ты думал заполучить все на халяву?! :)

dave ★★★★★
()
Ответ на: комментарий от dave

взвешивал варианты с многопоточностью. у нее есть минусы которые определяютяс тем что у потоков общее адресное пространство. Например, сигфолт в чужом коде будет фатален для всего приложения, а если использовать fork+execl, то это более безопасно, но и велосипедно в плане отслеживания состояния другого процесса.

ocr
() автор топика
Ответ на: комментарий от ocr

Ну, тут выбор - либо общие данные (многопоточность), либо изолированность (процессы). А кластерах пока не говорим.

dave ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.