Это ошибка в Ubuntu. В /etc/init/php5-fpm.conf есть закомментированная строка reload signal USR2
, которая заставляет функцию reload завершить ведущий процесс php5-fpm, отправив SIGHUP. Любые дальнейшие перезагрузки, перезапуски или остановки будут неудачными, потому что основной процесс был завершен.
Я исправил это в Ubuntu 14.04, создав файл /etc/init/php5-fpm.override
с одной строкой reload signal USR2
. Кредиты на комментарий Юриана Слуймана в этот ответ .
Вот основной отчет об ошибке , предложенные обходные пути и подтверждение обходного пути .
$ ps aux | grep php
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1966 0.0 0.9 473276 37040 ? Ss 10:03 0:00 php-fpm: master process (/etc/php5/fpm/php-fpm.conf)
www-data 2009 0.0 1.5 478280 62500 ? S 10:03 0:01 php-fpm: pool www
www-data 2011 0.0 1.3 476504 55220 ? S 10:03 0:00 php-fpm: pool www
www-data 2012 0.0 1.6 481592 65840 ? S 10:03 0:00 php-fpm: pool www
$ sudo service php5-fpm status
php5-fpm start/running, process 1966
$ sudo service php5-fpm stop
php5-fpm stop/waiting
$ sudo service php5-fpm status
php5-fpm stop/waiting
$ sudo service php5-fpm start
php5-fpm start/running, process 2651
$ sudo service php5-fpm status
php5-fpm start/running, process 2651
$ ps aux | grep php
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2651 0.2 0.9 473276 36996 ? Ss 10:35 0:00 php-fpm: master process (/etc/php5/fpm/php-fpm.conf)
www-data 2654 0.0 0.1 473276 7104 ? S 10:35 0:00 php-fpm: pool www
www-data 2655 0.0 0.1 473276 7104 ? S 10:35 0:00 php-fpm: pool www
www-data 2656 0.0 0.1 473276 7104 ? S 10:35 0:00 php-fpm: pool www
Когда я сталкиваюсь с этой ситуацией, я использую написанный мной класс под названием ThreadAffinity. Вся его цель - записать текущий поток и выдать недопустимые обращения из другого потока. Вы должны выполнить проверку вручную, но она включает небольшой объем работы за вас.
class Foo {
ThreadAffinity affinity = new ThreadAffinity();
public string SomeProperty {
get { affinity.Check(); return "Somevalue"; }
}
}
Class
[Immutable]
public sealed class ThreadAffinity
{
private readonly int m_threadId;
public ThreadAffinity()
{
m_threadId = Thread.CurrentThread.ManagedThreadId;
}
public void Check()
{
if (Thread.CurrentThread.ManagedThreadId != m_threadId)
{
var msg = String.Format(
"Call to class with affinity to thread {0} detected from thread {1}.",
m_threadId,
Thread.CurrentThread.ManagedThreadId);
throw new InvalidOperationException(msg);
}
}
}
Сообщение в блоге на эту тему:
Не могли бы вы потребовать, чтобы методы чтения и записи принимали поток или идентификатор потока? Затем вы можете просто сравнить с тем, который вызвал его первым, и, если он не совпадает, выбросить исключение или вернуть код ошибки или проигнорировать запрос.
В противном случае то, что вы предлагаете, также должно работать. Вам нужно только сравнить идентификаторы потоков.
Вместо того, чтобы сравнивать идентификаторы потоков, вы должны сохранить внешний поток в своем классе во время создания.
class SingleThreadedClass
{
private Thread ownerThread;
public SingleThreadedClass()
{
this.ownerThread = Thread.CurrentThread;
}
public void Read(...)
{
if (Thread.CurrentThread != this.ownerThread)
throw new InvalidOperationException();
}
public void TakeOwnership()
{
this.ownerThread = Thread.CurrentThread;
}
}