Добрый вечер.
Sorry за глупый вопрос, вычитал что прототип для fork() выглядит так:
pid_t fork(void);
А void, если я правильно понимаю, чаще означает «необязательно» чем «отсутствует». Значит ли это, что через fork() можно передать параметр для «потомка»?
Пробовал так:
fork("1");
и так:
fork(1);
В обоих случаях потомок создается, но в выводе ps -ax |grep MyProgram значилось просто 2 экземпляра моей наколенки, без параметра.
Собственно вопрос: можно ли выполняя fork() явным образом указать параметры ком.строки, что бы было видно потом их в списке процессов?
читай что такое форк. если мурзилка стаил то порождается новый процесс с точки вызова форка который наследует страницы и контекст порождающего процесса.
Товарисч, читай маны по fork и exec. Fork — это не запуск программы с ее начала, а расщепление процесса на два, при этом один идет по одной ветке условия «if (pid = fork())», а второй - по другой. При этом можно считать, что копируется весь образ процесса (хотя технически там CoW). А вот exec — это уже замена образа текущей исполняемой программы образом с диска по указанному пути с указанными argv, argc и envp. И в него можно передавать аргументы.
А void, если я правильно понимаю, чаще означает «необязательно» чем «отсутствует».
Нет, не правильно.
В Си func(void) определяет функцию, у которой нет аргументов, а func() — функцию с любым числом аргуметов. В Си++ оба варианта означают, что агрументов нет.
Хех, как накинулись-то! ))
Отвечая на вопрос «Зачем?»
- хотел «быстро» и с минимальными телодвижениями упростить администрирование собственного сервера (для каждого подключившегося вызывается тот самый fork() и в нем идет обработка). По ps -ax можно понять сколько в данный момент времени подключившихся клиентов, но было бы существенно наглядней, если бы у каждого было бы подписано:
Естественно я не собираюсь эти параметры как-то обрабатывать - мне это действительно не нужно! )))
PS. Варианты с exec тоже читал, но сервер уже написан и функционирует на fork'ах. Переписывать его из-за случайно возникшей блажи - лень, уж скорее вставлю запись в файл пида/логина/ip:port, а в OnExit() - удаление оной строчки с тем, что бы далее парсить один файл понятного формата...
PS2. Исходя из стремления к увеличению сугубо наглядности, но помня о природной лени, вариант с файлом, хранящим список онлайн: оптимальный? Или есть еще более «простой» (элегантный) способ??! ))
Когда говорят «что угодно», имеется в виду конкретная реализация. Если, например, в ABI результат функции возвращается в %rax, и при этом ты перепутаешь сигнатуры функций (в одной единице трансляции определишь функцию как void func() {}, а в другой как int func()), то при вызове int var = func() в var действительно может что-то непонятное попасть. Компилятор положит в эту переменную значение регистра %rax.
«имеется в виду конкретная реализация»
- Ну да, сам, помню, писал такое:
void myFunction()
{
if (event) return 5;
}
и компилятор компилил. Предупреждение было, но что-то собиралось и даже как-то работало (давно дело было). Тогда и уверился что «так можно», спасибо - разжевали)
«Т.е. у вас выполняется fork(), но после нету exec()? Неожиданное решение, в таких случаях обычно используются потоки.»
- Именно, в switch (fork()) вставлен «рабочий цикл». Просто в свое время был взят готовый пример «многопоточного сервера» на просторах, и дописан. А потоки накладывали уйму «усложнений», у меня обработка клиентов «независимая», в потоках пришлось бы расставлять/следить за симафорами при использовании буферов... в общем - лень победила: копи/паст + малость подредактировали и use))
«netstat на вас нет»
- Вот честно: я аж с утра проверю/отпишусь... он (netstat) умеет говорить с какого компа/порта какой пользователь прицепился? Учитывая, что клиент на шарпе цепляется (могут несколько разных пользователей с одного компа, может 1 пользователь с разных компов) к «серверной» части на си и «стучится» под логином/паролем, существующими сугубо в рамках этих приложений?? ))
«Хак конечно, но что мешает заменить argv[1] собственно?»
- А вот это, по моему, самое то!!! ))))))
Спасибо, с утра проверю, если оно: ваще-вааще спасибо!!! ))))
- Руки чешутся попробовать, но уже всё повыключал - спать пора, утром проверю... По моему, этот вариант выглядит кошернее чем подмена в argv[], спасибо! ))
Можно выделить несколько переменных, а после форка записывать нужные значения в них для каждого подпроцесса. Можно аж целые структуры создавать. В любом случае, логика остается на основании данных род.процесса (копия как никак).
Как я уже оговорился: тестирую я всё на убунте, тут вопросов «что брать» не возникает. Сервак же крутится на RedHat'e, скажу честно - я совершенно не спец в данном вопросе, а потому: что из вышеописанного списка нужно скачать(заинклудить?) что бы бинарник потом корректно выполнился и на тесте в убунте и в «боевых условиях» на редхате?
Разве информации из первой строки исходника не достаточно?
- А-а-а-а!!! ))))))
Сори, оно же закаменчено, кто те коменты читает? ШУТКА!!! )))
Каюсь - олень, протупил, спасибо!!! ))))
Не путай void и void*
- Мне бы даже стыдно бы было бы, если бы не было так грустно. При работе с указателями (*) я парюсь всегда. Магия ссылки/разъименования и подобное для меня «за гранью» понимания! Читал... в разное время разных авторов, всё-равно каша в голове. ((
Оттого, отчасти, и не стал юзать pthread (там бы 100% пришлось ставить мьютексы-семафоры и кидаться ссылками в функции потоков). В тех редких случаях, когда не получается выкрутиться, дабы работать со значениями я чаще всего ищу решение методом тыка: клепаю наколенку, в которой вывожу printf() все, возможные варианты *point, point, &point, * *point и уже из этого вывода пытаюсь угадать который вариант мне нужно использовать... не всегда удается с первого раза))))