سؤال

أنا أستخدم جزء التعليمات البرمجية التالي في برنامج نصي 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.تكشف صفحة الدليل أن استدعاء النظام semop() تمت مقاطعته بواسطة إشارة.

سؤالي هو هل يمكنني تجاهل هذا الخطأ بأمان وإعادة محاولة sem_acquire؟

يحرر:لقد أساءت فهم هذه المشكلة، يرجى الاطلاع على التوضيح الذي نشرته أدناه.

راج

هل كانت مفيدة؟

المحلول

وأود أن لا نتجاهل ENOSPC (كنت الحصول على شيء آخر غير EINTR، كما يظهر رمز). قد ينتهي بك الأمر في حلقة مشغول انتظار المورد الذي قد استنفدت في وقت سابق. إذا كنت من بعض المساحة في مكان ما، وتريد للتأكد من أن تتعامل مع هذه المسألة. ENOSPC يعني عموما كنت خارج ... شيء.

وزوجان من الأفكار العشوائية:

وأنا لست خبيرا بشأن تنفيذ PHP، ولكن كنت في محاولة لتجنب يدعو sem_get() في كل مرة تريد الإشارة. تخزين مقبض بدلا من ذلك. قد يكون مقترن بعض الموارد مع كل استدعاء sem_get، وهذا هو المكان الذي ينفد من الفضاء.

وكنت لفحص للتأكد عوائد خطأ الخاص بك على sem_get(). انها التعليمات البرمجية المتكررة، ولكن إذا كانت لتفشل في الحصول على sema4، ستحصل نتائج غير متناسقة عند محاولة sem_op() ذلك (ربما EINTR المنطقي)

نصائح أخرى

بعد نشر هذا السؤال لاحظت أنني أخطأت في قراءة الكود على أنه errno == EINTR وقفز إلى الاستنتاج.لذا، كما أشار بوج، فإن الخطأ هو ENOSPC و لا EINTR.وبعد بعض البحث وجدت السبب ENOSPC.تم استنفاد عدد المخازن المؤقتة للتراجع.لقد قمت بزيادة عدد semmnu والآن يعمل الكود بدون مشاكل.لقد استخدمت semmni*semmsل كقيمة semmnu

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top