Ошибка EINTR для вызова semop - PullRequest
1 голос
/ 07 ноября 2008

Я использую следующий фрагмент кода в php-скрипте для безопасного обновления общего ресурса.

$lock_id = sem_get( ftok( 'tmp/this.lock', 'r'));
sem_acquire($lock_id)
//do something
sem_release($lock_id)

Когда я тестирую этот код с большим количеством запросов, я получаю сообщение об ошибке:

Warning: semop() failed acquiring SYSVSEM_SETVAL for key 0x1e: No space left on device in blahblah.php on line 1293

Источники php показывают следующий код для неудачного получения SYSVSEM_SETVAL

while (semop(semid, sop, 3) == -1) {
    if (errno != EINTR) {
        php3_error(E_WARNING, "semop() failed acquiring SYSVSEM_SETVAL for key 0x%x: %s", key, strerror(errno));
        break;
    }
}

, что означает, что semop не работает с EINTR. Страница man показывает, что системный вызов semop () был прерван сигналом.

Мой вопрос: можно ли безопасно проигнорировать эту ошибку и повторить попытку sem_acquire?

Редактировать : Я неправильно понял эту проблему, см. Пояснение, которое я разместил ниже.

Радж

Ответы [ 2 ]

1 голос
/ 07 ноября 2008

Я бы не стал игнорировать ENOSPC (как показано в коде, вы получаете что-то отличное от EINTR). Вы можете оказаться в занятом цикле, ожидая ресурс, который вы ранее исчерпали. Если у вас где-то не хватает места, вам нужно убедиться, что вы справляетесь с этой проблемой. ENOSPC обычно означает, что вы вне ... чего-то.

Пара случайных идей:

Я не эксперт по реализации PHP, но я бы старался не вызывать sem_get() каждый раз, когда вам нужен семафор. Храните ручку вместо этого. Может случиться так, что какой-то ресурс связан с каждым вызовом sem_get, и именно здесь у вас заканчивается свободное пространство.

Я бы обязательно проверил ваши ошибки на sem_get(). Это фрагмент кода, но если вам не удастся получить sema4, вы получите непоследовательные результаты при попытке sem_op() (возможно, EINTR имеет смысл)

0 голосов
/ 07 ноября 2008

После публикации этого вопроса я заметил, что неправильно прочитал код как errno == EINTR и пришел к выводу. Итак, как указало болото, ошибка составляет ENOSPC, а не EINTR. После некоторых раскопок я нашел причину ENOSPC. Количество буферов отмены истощалось. Я увеличил число semmnu, и теперь код работает без проблем. Я использовал semmni*semms l в качестве значения semmnu

...