shmget(2)

الاسم
shmget - يخصص مقطع ذاكرة مشتركة من النوع System V

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);

الوصف
تُرجع shmget() معرف مقطع الذاكرة المشتركة من النوع System V المرتبط بقيمة الوسيط key. يمكن استخدامها إما للحصول على معرف مقطع ذاكرة مشتركة تم إنشاؤه سابقًا (عندما يكون shmflg صفرًا ولا يحمل key القيمة IPC_PRIVATE)، أو لإنشاء مجموعة جديدة.

يُُنشأ مقطع ذاكرة مشتركة جديد، بحجم يساوي قيمة size مقربًا لأعلى إلى مضاعف PAGE_SIZE، إذا كان key يحمل القيمة IPC_PRIVATE أو لم يكن key هو IPC_PRIVATE، ولا يوجد مقطع ذاكرة مشتركة مطابق لـ key، وتم تحديد IPC_CREAT في shmflg.

إذا حدد shmflg كلاً من IPC_CREAT و IPC_EXCL وكان مقطع ذاكرة مشتركة موجودًا بالفعل لـ key، فإن shmget() تفشل مع تعيين errno إلى EEXIST. (هذا مماثل لتأثير الدمج O_CREAT | O_EXCL لـ open(2).)

تتكون القيمة shmflg من:

IPC_CREAT
    إنشاء مقطع جديد. إذا لم يُستخدم هذا العلم، فسيعثر shmget() على المقطع المرتبط بـ key ويتحقق مما إذا كان المستخدم لديه الإذن للوصول إلى المقطع.

IPC_EXCL
    يُستخدم هذا العلم مع IPC_CREAT لضمان أن هذه الاستدعاء تنشئ المقطع. إذا كان المقطع موجودًا بالفعل، تفشل الاستدعاء.

SHM_HUGETLB (منذ Linux 2.6)
    تخصيص المقطع باستخدام صفحات "ضخمة". راجع ملف مصدر نواة لينكس Documentation/admin-guide/mm/hugetlbpage.rst لمزيد من المعلومات.

SHM_HUGE_2MB
SHM_HUGE_1GB (منذ Linux 3.8)
    يُستخدم بالتزامن مع SHM_HUGETLB لاختيار أحجام صفحات hugetlb بديلة (2 ميجابايت و 1 جيجابايت على التوالي) على الأنظمة التي تدعم أحجام صفحات hugetlb متعددة.

    بشكل أعم، يمكن تكوين حجم الصفحة الضخمة المطلوب عن طريق ترميز اللوغاريتم ذو الأساس 2 لحجم الصفحة المطلوب في البتات الستة عند الإزاحة SHM_HUGE_SHIFT. وبالتالي، يتم تعريف الثابتين أعلاه على النحو التالي:

        #define SHM_HUGE_2MB    (21 << SHM_HUGE_SHIFT)
        #define SHM_HUGE_1GB    (30 << SHM_HUGE_SHIFT)

    لمزيد من التفاصيل الإضافية، راجع مناقشة الثوابت المسماة بالمثل في mmap(2).

SHM_NORESERVE (منذ Linux 2.6.15)
    يخدم هذا العلم نفس الغرض الذي يخدمه علم MAP_NORESERVE في mmap(2). لا تحجز مساحة مبادلة لهذا المقطع. عند حجز مساحة المبادلة، يكون لديك ضمان بإمكانية تعديل المقطع. عندما لا تُحجز مساحة المبادلة، قد تحصل على SIGSEGV عند الكتابة إذا لم تكن ذاكرة فيزيائية متاحة. راجع أيضًا مناقشة الملف /proc/sys/vm/overcommit_memory في proc_sys_vm(5).

بالإضافة إلى الأعلام أعلاه، تحدد أقل 9 بتات أهمية من shmflg الأذونات الممنوحة للمالك والمجموعة والآخرين. لهذه البتات نفس التنسيق ونفس المعنى مثل وسيط mode لـ open(2). حاليًا، لا يستخدم النظام أذونات التنفيذ.

عند إنشاء مقطع ذاكرة مشتركة جديد، تتم تهيئة محتوياته إلى قيم صفرية، ويتم تهيئة بنية البيانات المرتبطة به، shmid_ds (انظر shmctl(2))، على النحو التالي:

•   يتم تعيين shm_perm.cuid و shm_perm.uid إلى معرف المستخدم الفعّال للعملية المستدعية.

•   يتم تعيين shm_perm.cgid و shm_perm.gid إلى معرف المجموعة الفعّال للعملية المستدعية.

•   يتم تعيين أقل 9 بتات أهمية من shm_perm.mode إلى أقل 9 بتات أهمية من shmflg.

•   يتم تعيين shm_segsz إلى قيمة size.

•   يتم تعيين shm_lpid و shm_nattch و shm_atime و shm_dtime إلى 0.

•   يتم تعيين shm_ctime إلى الوقت الحالي.

إذا كان مقطع الذاكرة المشتركة موجودًا بالفعل، يتم التحقق من الأذونات، ويتم إجراء فحص لمعرفة ما إذا كان مُعلّمًا للتدمير.

قيمة الإرجاع
عند النجاح، يتم إرجاع معرف ذاكرة مشتركة صالح. عند الخطأ، يتم إرجاع -1، ويتم تعيين errno للإشارة إلى الخطأ.

الأخطاء

EACCES
    المستخدم لا يملك صلاحية الوصول إلى قطعة الذاكرة المشتركة، ولا يملك القدرة CAP_IPC_OWNER في نطاق المستخدم الذي يحكم نطاق IPC الخاص به.

EEXIST
    تم تحديد IPC_CREAT و IPC_EXCL في shmflg، ولكن قطعة ذاكرة مشتركة موجودة بالفعل للمفتاح key.

EINVAL
    كان من المقرر إنشاء قطعة جديدة و size أقل من SHMMIN أو أكبر من SHMMAX.

EINVAL
    توجد قطعة للمفتاح key المعطى، ولكن size أكبر من حجم تلك القطعة.

ENFILE
    وُصل إلى الحد الأقصى لإجمالي عدد الملفات المفتوحة على مستوى النظام.

ENOENT
    لا توجد قطعة للمفتاح key المعطى، ولم يتم تحديد IPC_CREAT.

ENOMEM
    لا يمكن تخصيص ذاكرة للنفقات العامة للقطعة.

ENOSPC
    تم أخذ جميع معرفات الذاكرة المشتركة الممكنة (SHMMNI)، أو تخصيص قطعة بالحجم size المطلوب سيتسبب في تجاوز النظام للحد النظامي على الذاكرة المشتركة (SHMALL).

EPERM
    تم تحديد العلم SHM_HUGETLB، ولكن المتصل لم يكن متميزًا (لم يملك القدرة CAP_IPC_LOCK) وليس عضوًا في مجموعة hugetlb_shm_group؛ انظر وصف /proc/sys/vm/hugetlb_shm_group في proc_sys_vm(5).

المعايير
POSIX.1-2024.

SHM_HUGETLB و SHM_NORESERVE هما امتدادات لينكس.

التاريخ
POSIX.1-2001، SVr4.

ملاحظات
IPC_PRIVATE ليس حقل علم بل نوع key_t. إذا تم استخدام هذه القيمة الخاصة لـ key، تتجاهل استدعاء النظام كل شيء باستثناء أقل 9 بتات أهمية من shmflg وتنشئ قطعة ذاكرة مشتركة جديدة.

  حدود الذاكرة المشتركة
الحدود التالية على موارد قطعة الذاكرة المشتركة تؤثر على استدعاء shmget() :

SHMALL
    الحد النظامي على إجمالي كمية الذاكرة المشتركة، مقاسًا بوحدات حجم صفحة النظام.

    في لينكس، يمكن قراءة هذا الحد وتعديله عبر /proc/sys/kernel/shmall. منذ لينكس 3.16، القيمة المبدئية لهذا الحد هي:

        ULONG_MAX - 2^24

    تأثير هذه القيمة (المناسبة لكل من الأنظمة 32-بت و 64-بت) هو عدم فرض أي قيود على التخصيصات. تم اختيار هذه القيمة، بدلاً من ULONG_MAX، كقيمة مبدئية لمنع بعض الحالات حيث رفعت التطبيقات التاريخية الحد الحالي ببساطة دون التحقق أولاً من قيمته الحالية. مثل هذه التطبيقات ستتسبب في تجاوز القيمة إذا تم تعيين الحد عند ULONG_MAX.

    من لينكس 2.4 حتى لينكس 3.15، كانت القيمة المبدئية لهذا الحد:

        SHMMAX / PAGE_SIZE * (SHMMNI / 16)

    إذا لم يتم تعديل SHMMAX و SHMMNI، فإن ضرب نتيجة هذه الصيغة بحجم الصفحة (للحصول على قيمة بالبايت) ينتج قيمة 8 جيجابايت كحد على إجمالي الذاكرة المستخدمة بواسطة جميع قطع الذاكرة المشتركة.

SHMMAX
    الحد الأقصى للحجم بالبايت لقطعة ذاكرة مشتركة.

    في لينكس، يمكن قراءة هذا الحد وتعديله عبر /proc/sys/kernel/shmmax. منذ لينكس 3.16، القيمة المبدئية لهذا الحد هي:

        ULONG_MAX - 2^24

    تأثير هذه القيمة (المناسبة لكل من الأنظمة 32-بت و 64-بت) هو عدم فرض أي قيود على التخصيصات. انظر وصف SHMALL لمناقشة سبب استخدام هذه القيمة المبدئية (بدلاً من ULONG_MAX).

    من لينكس 2.2 حتى لينكس 3.15، كانت القيمة المبدئية لهذا الحد 0x2000000 (32 ميجابايت).

    لأنه ليس من الممكن تعيين جزء فقط من قطعة ذاكرة مشتركة، تضع كمية الذاكرة الافتراضية حدًا آخر على الحجم الأقصى لقطعة قابلة للاستخدام: على سبيل المثال، على i386 أكبر القطع التي يمكن تعيينها يبلغ حجمها حوالي 2.8 جيجابايت، وعلى x86-64 الحد حوالي 127 تيرابايت.

SHMMIN
    الحد الأدنى للحجم بالبايت لقطعة ذاكرة مشتركة: يعتمد على التنفيذ (حاليًا 1 بايت، على الرغم من أن PAGE_SIZE هو الحد الأدنى الفعلي).

SHMMNI
    الحد النظامي على عدد قطع الذاكرة المشتركة. في لينكس 2.2، كانت القيمة المبدئية لهذا الحد 128؛ منذ لينكس 2.4، القيمة المبدئية هي 4096.

    في لينكس، يمكن قراءة هذا الحد وتعديله عبر /proc/sys/kernel/shmmni.

لا يحتوي التطبيق على حدود محددة للعدد الأقصى لقطاعات الذاكرة المشتركة لكل عملية (SHMSEG).

  ملاحظات لينكس
حتى لينكس 2.3.30، كان لينكس يُرجع EIDRM لاستدعاء shmget() على قطاع ذاكرة مشتركة مجدول للحذف.

العلل
ربما كان اختيار الاسم IPC_PRIVATE غير موفق، فاسم IPC_NEW كان سيظهر وظيفتها بشكل أوضح.

أمثلة
انظر shmop(2).

انظر أيضًا
memfd_create(2)، shmat(2)، shmctl(2)، shmdt(2)، ftok(3)، capabilities(7)، shm_overview(7)، sysvipc(7)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.