كيف يمكنني إيقاف فشل sem_open() مع ENOSYS؟
سؤال
لدي نظامان من أنظمة Slackware Linux التي تحتوي على إشارة POSIX sem_open()
فشل الاتصال مع تعيين errno على 38.نموذج التعليمات البرمجية المراد إعادة إنتاجه أدناه (يعمل الكود بشكل جيد على CentOS/RedHat).
هل هناك أي خيارات لتكوين النواة أو النظام يمكن أن تسبب هذا؟اقتراحات أخرى؟
الأنظمة التي بها مشكلة هي Slackware 10.1.0 kernel 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so، ولكن نفس الكود يعمل على RedHat 9 kernel 2.4.20 /lib/librt الأقدم بكثير -2.3.2.so /lib/tls/libpthread-0.29.so.(ويعمل أيضًا على CentOS 5 kernel 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so).
man sem_open
يقترح هذا يعني errno sem_open()
غير مدعوم من قبل النظام.
#define ENOSYS 38 /* Function not implemented */
ال sem_open()
مساحة المستخدم موجودة librt
التي نربطها ديناميكيًا و librt
موجود على الأنظمة المتضررة.
يدعي النظام المتأثر أنه يدعم إشارات POSIX: _POSIX_SEMAPHORES
صحيح و sysconf(_SC_SEMAPHORES)
يؤكد هذا.
شكرا ، كيران
تحرير 1:لقد أضفت مزيدًا من التفاصيل حول إصدارات البرامج المستخدمة وقمت بإزالة بعض التعليقات غير ذات الصلة.
تحرير 2:/dev/shm يتم تثبيته على الأنظمة الجيدة ولا يتم تثبيته على الأنظمة السيئة.لم يؤدي تثبيته إلى تغيير السلوك على الأنظمة المتأثرة.أعتقد أن /dev/shm ضروري أيضًا ولكن sem_open() يفشل قبل ذلك، ويدعم strace هذا.
# /* Quick'n'dirty test program to illustrate sem_open failure
#Run this file to auto-build test and run as a.out
# Build
gcc $0 -lrt
if [ $? -ne 0 ] ; then exit ; fi
# Run
$( dirname $0)/a.out
exit
*/
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <semaphore.h>
int main(int argc, char *argv[]) {
const char *SEM_NAME = "SHRMEM_SCXL"; /* name of mutex */
sem_t *mutex = SEM_FAILED; /* ptr to mutex */
#ifdef _POSIX_SEMAPHORES
printf("_POSIX_SEMAPHORES %ld\n", _POSIX_SEMAPHORES);
#else
puts("Undefined");
#endif
printf("sysconf %s\n", sysconf(_SC_SEMAPHORES) ? "Yes" : "No" );
mutex = sem_open(SEM_NAME, O_CREAT, 0666, 1);
if (mutex == SEM_FAILED) printf("Failed %d\n", errno);
else {
puts("Success - pause while you check /dev/shm ");
sleep(5);
sem_close(mutex);
sem_unlink(SEM_NAME);
}
}
المحلول
وهي التي شنت / ديف / SHM؟ الإصدارات القديمة من سلاكوير قد لا يكون شنت هذه الملفات في التمهيد. من / الخ / fstab:
tmpfs /dev/shm tmpfs defaults 0 0
وتحرير: وهذا هو الأرجح ليست المشكلة بعد كل شيء. وأعتقد أنك قد تحتاج فقط إلى ترقية نواة أو ربما حتى librt.
وEdit2: أعتقد ذلك، سوف تحتاج لسلاكوير 11، التي أعتقد أنك تستخدم نواة أحدث من 2.6.13 لاستخدام NPTL خيوط المكتبات (يبس في / ليب / TLS) التي يبدو أنها تكون هناك حاجة ل وsem_open للعمل.
وEdit3: تمكنت من الحصول عليها للعمل مع مربع سلاكوير 11 لدي كتبها أ) تركيب / ديف / SHM وب) وضع البيئة LD_ASSUME_KERNEL
متغير ل2.6.13 (أي إصدار نواة> 2.6.12 ستعمل) . ويبدو أن العمل على الرغم من أن النواة 2.6.11.11، ولكن أشياء أخرى مثل المواضيع قد لا.
نصائح أخرى
لا تدعم الإصدارات الأقدم من مكتبات الترابط مشاركة إشارات POSIX بين العمليات.من man sem_init
تشير الوسيطة Pshared إلى ما إذا كانت الإشارة المحلية في العملية الحالية (Pshared هي صفر) أو يجب مشاركتها بين عدة عمليات (Pshared ليس صفرًا).لا يدعم LinuxTreads حاليًا الإشارات المشتركة للعملية ، وبالتالي فإن SEM_Init يعود دائمًا مع Error Enosys إذا لم يكن Pshared صفرًا.
عندما يقوم الدالة sem_open() بإنشاء إشارات مسماة، فإنه يحاول دائمًا مشاركتها بين العمليات.
لدعم مشاركة الإشارات المجهولة بين العمليات باستخدام sem_init() على Slackware 10
- ترقية libpthread و (ربما) librt
- ترقية النواة
بالإضافة إلى ذلك، لدعم مشاركة الإشارات المسماة مع sem_open()
إضافة خط إلى
/etc/fstab
لتحميل/dev/shm
كتمفسtmpfs /dev/shm الافتراضيات tmpfs 0 0
يجري
mount /dev/shm
أو إعادة التشغيل
إن فرضية "عملية sema4 المشتركة لا تعمل" تبدو منطقية بالنسبة لي.لا يعني ذلك أن هذا يساعدك، ولكن إذا كان لديك الوقت والرغبة، فقد ترغب في تجربة ما يلي، لمعرفة ما إذا كان جانب "العملية المشتركة" هو سبب الفشل:
إنشاء إشارة باستخدام sem_init في الذاكرة غير المشتركة (للخيوط).إذا كان يعمل فإن sema4s يعمل ضمن هذه العملية.
كرر التجربة في الذاكرة المشتركة.يجب أن يخبرك هذا إذا كانوا يعملون بين العمليات.لاحظ أنك قد تحتاج بالفعل إلى محاولة استخدام sema4 لمعرفة ما إذا كان يعمل بين العمليات.
وهناك طريقة أخرى لمشاركة إشارة عبر العمليات هو استخدام الإشارات SystemV.
وهذه لا تعمل حتى عندما المشتركة الإشارات POSIX لا (على الأقل على أنظمة المذكورة أعلاه).
HTTP: // www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html للحصول على أمثلة من هذين النوعين من استخدام الإشارة.
وكنت أعمل مع طوابير رسالة POSIX لقد حصلت على وفشل نفس mq_open الخطأ مع errono 38 (ENOSYS).
والعمل: حول هو إعادة بناء kenel مع POSIX من messge QUEUE تمكين في تكوين النواة.
وهذا سوف بناء النواة مع دعم POSIX قائمة انتظار الرسائل وأنها عملت لي.
والشكر