У меня очень простой C-сервер: основной процесс - прослушивание определенного порта. Когда приходит новый запрос, вызывается fork (): дочерний процесс входит в функцию под названием dosomething (), возвращает ответ клиенту, регистрирует все в текстовом файле и затем умирает. Это упрощенный вид:
void dosomething(int socketFd)
{
/* ... */
//Reads the request and sends a response
writetolog("[INFO] Request accepted. Sent response message -> ", buffer);
/* ... */
}
Это функция регистрации:
void writetolog(char* logString1, char* logString2)
{
/* ... */
//Prepends date and time, and formats everything nicely into a single char[]
if ((logFd = open("SocketServer.log", O_CREAT | O_WRONLY | O_APPEND, 0644)) >= 0) {
write(logFd, logBuffer, strlen(logBuffer));
close(logFd);
}
}
Теперь мой вопрос: поскольку этот сервер (теоретически) способен обрабатывать несколько запросов одновременно (поэтому несколько процессов могут захотеть записать что-то в журнал), нужно ли вводить какую-либо логику синхронизации (блокировки) для журнала файл
Учитывая, что "критическая секция" - это тот единственный вызов write ():
Может ли несколько вызовов write () для одного и того же файлового дескриптора быть «смешанными» из-за планирования ОС? Это реальный риск?
Например:
Process1 wants to write "ABC"
Process2 wants to write "123"
Result: "AB1C23"
Я попытался отправить тысячи запросов от трех разных клиентов в одно и то же время. Файл журнала записывался правильно каждый раз, без «смешения». Можно ли сделать вывод, что системный вызов write () является атомарным , по крайней мере, в POSIX-совместимых системах?
Бонусный вопрос : допустим, что функция регистрации использует два вызова write () вместо одного. Механизм синхронизации больше не должен быть необязательным, потому что я хочу убедиться, что два вызова выполняются без прерывания другим процессом. Какой простейший объект блокировки я должен использовать в этом случае? Mutex будет достаточно?