Ответ
В основном я работаю с Linux (различные дистрибутивы: Ubuntu, Fedora, CentOS) как основной платформой для разработки и развёртывания серверных приложений на C++. Для кросс-платформенной разработки и отладки также использую Windows. Имею опыт работы с QNX и FreeRTOS при разработке встраиваемых и систем реального времени.
Пример из практики (Linux): При разработке сетевого демона на C++ активно использовал системные вызовы для управления процессами и межпроцессного взаимодействия (IPC).
#include <unistd.h>
#include <sys/wait.h>
#include <iostream>
#include <cstdlib>
int main() {
pid_t pid = fork(); // Создание дочернего процесса
if (pid == -1) {
std::cerr << "Fork failed!" << std::endl;
return EXIT_FAILURE;
}
if (pid == 0) {
// Код, выполняемый в дочернем процессе
std::cout << "Child process PID: " << getpid() << std::endl;
// Заменяем образ процесса на выполнение команды 'ls'
execlp("/bin/ls", "ls", "-l", nullptr);
// Если execlp вернул управление, значит, произошла ошибка
std::cerr << "execlp failed!" << std::endl;
exit(EXIT_FAILURE);
} else {
// Код, выполняемый в родительском процессе
std::cout << "Parent process PID: " << getpid() << ", child PID: " << pid << std::endl;
int status;
waitpid(pid, &status, 0); // Ожидание завершения дочернего процесса
if (WIFEXITED(status)) {
std::cout << "Child exited with status: " << WEXITSTATUS(status) << std::endl;
}
}
return EXIT_SUCCESS;
}
Работа с разными ОС научила меня учитывать особенности системных API, управление памятью и планировщики задач при написании переносимого и эффективного кода на C++.
Ответ 18+ 🔞
Знаешь, как бывает — сидишь, пишешь код, а потом раз — и понимаешь, что твой софт должен бегать не только на твоём уютном убунту, но и на какой-нибудь загадочной железяке с QNX, где даже ls может оказаться роскошью. Ёпта, вот тут и начинается настоящий цирк.
В основном, конечно, я в Linux ковыряюсь — Ubuntu, Fedora, CentOS, всё это родное. На нём и серверные штуки кручу, и демонов пишу. Но жизнь — хитрая жопа, иногда приходится переползать на Windows, чтобы потестировать или отладить какую-нибудь кросс-платформенную дичь. А бывало и такое, что код должен был влететь в какую-то встраиваемую систему на FreeRTOS или в QNX — вот тут уже терпения ноль, ебать, потому что отлаживать — это отдельный вид искусства, почти как ювелирная работа с паяльником.
Вот, смотри, реальный пример из жизни (Linux): Пишем сетевого демона, и нужно, чтобы он порождал процессы, как кролики. Используем классику — fork() и exec(). Выглядит страшновато, но на деле логика проще пареной репы.
#include <unistd.h>
#include <sys/wait.h>
#include <iostream>
#include <cstdlib>
int main() {
pid_t pid = fork(); // Вот тут родился клон
if (pid == -1) {
std::cerr << "Fork failed!" << std::endl;
return EXIT_FAILURE;
}
if (pid == 0) {
// А это уже детка, новый процесс
std::cout << "Child process PID: " << getpid() << std::endl;
// Говорим ему: "Забудь всё, стань командой 'ls'"
execlp("/bin/ls", "ls", "-l", nullptr);
// Если добрались сюда — всё пошло по пизде, exec не сработал
std::cerr << "execlp failed!" << std::endl;
exit(EXIT_FAILURE);
} else {
// А это папаша, ждёт своего отпрыска
std::cout << "Parent process PID: " << getpid() << ", child PID: " << pid << std::endl;
int status;
waitpid(pid, &status, 0); // Сидит, курит, ждёт
if (WIFEXITED(status)) {
std::cout << "Child exited with status: " << WEXITSTATUS(status) << std::endl;
}
}
return EXIT_SUCCESS;
}
Вот после таких танцев с бубном вокруг разных ОС и понимаешь всю прелесть. На Linux одно API, на Windows — другое, на QNX — третье, и везде свои тараканы в планировщике задач и управлении памятью. Учишься писать код так, чтобы он не был привязан к одной платформе намертво, иначе потом будет тебе хиросима при портировании. В общем, опыт, бля, бесценный — хоть и выносит иногда мозг конкретно.