vcjaenhy
22.01.2020 - 20:29
Всем привет.
Ребят такой вопрос.
1) Запускаем скрипт создаем соединение с mysql
2) Далее с помощью pcntl разделяем процесс на родительский и 2 дочерних.
если я верно понимаю получается, что каждый процесс наследует (как бы сказать это правильно) ссылку на общее соединение?
Вопрос:
1) Если один процесс закроет соединение с mysql, что будет с соединением двух других?
2) Может ли возникнуть конфликтная ситуация при одновременной записи, редактировании данных в бд?
Zzepish
23.01.2020 - 00:31
vcjaenhy
1. В случае изменения данных в одном процессе - для него создается отдельная копия. Конкретно с соединениями я не экспериментировал, но что мешает проверить?)
2. Это разруливается на уровне самой субд, т.е. (в идеале) не должно. Но бывает всякое
Сам не пробовал именно с подключениями такого делать. Попробуешь - отпиши плз результат )
vcjaenhy
23.01.2020 - 01:06
наверно сразу стоит оговориться, что бы народ не путать, что сервер не апач а нджинкс. Апач долго симулировал работу...
Zzepish
понимаешь в чем проблема, я не думаю, что скрипом на колене можно такой вопрос решить, поэтому и завел на форуме топик.
Здесь как я понимаю тестирование нужно серьезное, нужно проц нагрузить и память. И наверно лучше это проверять сперва на одноядерной машине, далее на двуядерной. И лог должен быть быстрый. Верно мыслю?
И этот вопрос очень интересен так же для постгри, монго и редис
killer8080
23.01.2020 - 11:47
Цитата (vcjaenhy @ 22.01.2020 - 19:29) |
1) Запускаем скрипт создаем соединение с mysql 2) Далее с помощью pcntl разделяем процесс на родительский и 2 дочерних. |
никогда так не делай
Цитата (Zzepish @ 22.01.2020 - 23:31) |
1. В случае изменения данных в одном процессе - для него создается отдельная копия. Конкретно с соединениями я не экспериментировал, но что мешает проверить?) |
pcnt_fork это всего лишь обертка на системным вызовом fork() при этом копируется полностью память процесса, вместе со всеми переменными. Все ресурсы оказываются общими для клонов. Поэтому в точке форка не должно быть никаких открытых ресурсов. По завершении скрипта php закрывает все открытые ресурсы, первый завершившийся процесс закроет соединение с бд, даже если не было явного закрытия.
vcjaenhy
23.01.2020 - 16:57
killer рулит, и при том не в первый раз.
Т.е. получается подключение к бд необходимо проводить после разделения и при том индивидуально в каждом процессе?
Киллер, что если при в начале при подключении указать постоянное соединение с бд и юзать mysqli?
Zzepish
24.01.2020 - 00:19
killer8080
СТранно. Я где-то читал, что копирование происходит только при изменении ресурса, в противном случае - юзается из общей памяти (как строки - если одна строка, но несколько переменных с присвоенной одной строкой, то организуется просто несколько ссылок на одну область памяти).
Сам форк юзал вообще 1 раз, так-что не особо в нем силен. Спасибо за инфу.
vcjaenhy
Да, он реально крут
killer8080
24.01.2020 - 13:47
Цитата (vcjaenhy @ 23.01.2020 - 15:57) |
killer рулит, и при том не в первый раз. |
не преувеличивай
Цитата (vcjaenhy @ 23.01.2020 - 15:57) |
Т.е. получается подключение к бд необходимо проводить после разделения и при том индивидуально в каждом процессе? |
да
Цитата (vcjaenhy @ 23.01.2020 - 15:57) |
Киллер, что если при в начале при подключении указать постоянное соединение с бд и юзать mysqli? |
в CLI это бессмысленно. Pconnect может работать в жизненном цикле одного процесса, при завершении процесса постоянные соединения так же будут закрыты. Постоянные соединения имеют смысл только если скрипт исполняется воркером апача или fpm. В этом случае обработав один запрос интерпретатор делает зачистку и принимает следующий. Завершение скрипта не означает закрытие процесса, вот тут pconnect снижает оверхед на установку соединения с бд (и то целесообразность под вопросом), В CLI SAPI по завершении скрипта процесс умирает закрывая все открытые ресурсы. Есть хак, посылать SIGKILL самому себе, предотвращая корректное завершение работы процесса, но я бы не советовал так делать.
Кроме того есть вероятность коллизий запросов от разных процессов через одно соединение.
Поэтому сначала форк, а потом уже все подключения, это касается не только бд, но и любых других ресурсов.
Спустя 7 минут, 27 секунд killer8080 написал(а):
Цитата (Zzepish @ 23.01.2020 - 23:19) |
killer8080 СТранно. Я где-то читал, что копирование происходит только при изменении ресурса, |
тут я не в курсе, но даже если форк изначально copy-on-write во время работы состояние процесса будет меняться, какие то переменные будет создаваться, перезаписываться и т.д. то есть под форк все равно будет выделена память, и скопирован родительский процесс один в один, вместе со всеми переменными и id ресурсов. ОС не будет гадать какие ресурсы открыл процесс, и тем более за него открывать новые сокеты. Возможно я не прав, но тогда хотелось бы пруфов
killer8080 У тебя знаний и опыта вообще вагон!!!!
Хочу все знать так же как и ты
Zzepish
24.01.2020 - 22:16
killer8080
Цитата |
тут я не в курсе, но даже если форк изначально copy-on-write во время работы состояние процесса будет меняться, какие то переменные будет создаваться, перезаписываться и т.д. то есть под форк все равно будет выделена память, и скопирован родительский процесс один в один, вместе со всеми переменными и id ресурсов. ОС не будет гадать какие ресурсы открыл процесс, и тем более за него открывать новые сокеты. Возможно я не прав, но тогда хотелось бы пруфов |
<?php
$array = range(0, 10000000);
echo 'Main memory usage: '. ( memory_get_peak_usage() / 1024 / 1024 ) . 'MB' . PHP_EOL;
$pid = pcntl_fork();
if($pid == -1) {
die('Error occurred. Check if you have pcntl library (on windows you can\'t use pntlc)');
} elseif($pid) {
$cpid = pcntl_wait($status);
} else {
echo 'Child memory usage before code change: '. ( memory_get_peak_usage() / 1024 / 1024 ) . ' MB' . PHP_EOL;
$array = range(0, 10000000);
echo 'Child memory usage after code change: '. ( memory_get_peak_usage() / 1024 / 1024 ) . ' MB' . PHP_EOL;
}
Запусти этот скрипт :)
Быстрый ответ:
Powered by dgreen
Здесь расположена полная версия этой страницы.