.\" -*- coding: UTF-8 -*- .\" Copyright 1993, Giorgio Ciucci .\" Copyright 2020, Michael Kerrisk .\" Copyright, the authors of the Linux man-pages project .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH SHMOP 2 "8 فبراير 2026" "صفحات دليل لينكس 6.18" .SH الاسم shmat, shmdt \- عمليات الذاكرة المشتركة System V .SH المكتبة مكتبة سي المعيارية (\fIlibc\fP،\ \fI\-lc\fP) .SH موجز .nf \fB#include \fP .P \fBvoid *shmat(int \fP\fIshmid\fP\fB, const void *_Nullable \fP\fIshmaddr\fP\fB, int \fP\fIshmflg\fP\fB);\fP \fBint shmdt(const void *\fP\fIshmaddr\fP\fB);\fP .fi .SH الوصف .SS shmat() \fBshmat\fP() يربط مقطع الذاكرة المشتركة System\ V المحدد بواسطة \fIshmid\fP بمساحة عنوان العملية المستدعية. يتم تحديد عنوان الربط بواسطة \fIshmaddr\fP وفقًا لأحد المعايير التالية: .IP \[bu] 3 إذا كان \fIshmaddr\fP NULL، يختار النظام عنوانًا مناسبًا (غير مستخدم) محاذيًا للصفحة لربط المقطع. .IP \[bu] إذا لم يكن \fIshmaddr\fP NULL وتم تحديد \fBSHM_RND\fP في \fIshmflg\fP، يحدث الربط عند العنوان المساوي لـ \fIshmaddr\fP مقربًا إلى الأسفل لأقرب مضاعف لـ \fBSHMLBA\fP. .IP \[bu] خلاف ذلك، يجب أن يكون \fIshmaddr\fP عنوانًا محاذيًا للصفحة يحدث عنده الربط. .P بالإضافة إلى \fBSHM_RND\fP، يمكن تحديد الأعلام التالية في وسيطة قناع البت \fIshmflg\fP: .TP \fBSHM_EXEC\fP (خاص بلينكس؛ منذ لينكس 2.6.9) يسمح بتنفيذ محتويات المقطع. يجب أن يكون لدى المستدعي صلاحية التنفيذ على المقطع. .TP \fBSHM_RDONLY\fP يربط المقطع للوصول للقراءة فقط. يجب أن يكون لدى العملية صلاحية القراءة للمقطع. إذا لم يتم تحديد هذا العلم، يتم ربط المقطع للوصول للقراءة والكتابة، ويجب أن يكون لدى العملية صلاحيات القراءة والكتابة للمقطع. لا يوجد مفهوم لمقطع ذاكرة مشتركة للكتابة فقط. .TP \fBSHM_REMAP\fP (خاص بلينكس) يحدد هذا العلم أن تخطيط المقطع يجب أن يستبدل أي تخطيط موجود في النطاق الذي يبدأ من \fIshmaddr\fP ويستمر بحجم المقطع. (عادةً، ينتج خطأ \fBEINVAL\fP إذا كان هناك تخطيط موجود بالفعل في نطاق العنوان هذا.) في هذه الحالة، يجب ألا يكون \fIshmaddr\fP NULL. .P لا يتم تغيير قيمة \fBbrk\fP(2) للعملية المستدعية بواسطة الربط. سيتم فصل المقطع آليًا عند خروج العملية. يمكن ربط نفس المقطع كقراءة وكقراءة\-كتابة، وأكثر من مرة، في مساحة عنوان العملية. .P استدعاء \fBshmat\fP() ناجح يحدّث أعضاء بنية \fIshmid_ds\fP (انظر \fBshmctl\fP(2)) المرتبطة بمقطع الذاكرة المشتركة كما يلي: .IP \[bu] 3 يتم تعيين \fIshm_atime\fP إلى الوقت الحالي. .IP \[bu] يتم تعيين \fIshm_lpid\fP إلى معرف العملية للعملية المستدعية. .IP \[bu] .\" يتم زيادة \fIshm_nattch\fP بمقدار واحد. .SS shmdt() \fBshmdt\fP() يفصل مقطع الذاكرة المشتركة الموجود في العنوان المحدد بواسطة \fIshmaddr\fP من مساحة عنوان العملية المستدعية. يجب أن يكون المقطع المراد فصله مرتبطًا حاليًا مع \fIshmaddr\fP مساويًا للقيمة التي أرجعها استدعاء \fBshmat\fP() الرابط. .P عند استدعاء \fBshmdt\fP() ناجح، يحدّث النظام أعضاء بنية \fIshmid_ds\fP المرتبطة بمقطع الذاكرة المشتركة كما يلي: .IP \[bu] 3 يتم تعيين \fIshm_dtime\fP إلى الوقت الحالي. .IP \[bu] يتم تعيين \fIshm_lpid\fP إلى معرف العملية للعملية المستدعية. .IP \[bu] يتم إنقاص \fIshm_nattch\fP بمقدار واحد. إذا أصبح 0 وتم وضع علامة على المقطع للحذف، يتم حذف المقطع. .SH "قيمة الإرجاع" عند النجاح، تُرجع \fBshmat\fP() عنوان مقطع الذاكرة المشتركة المرفق؛ عند الخطأ، يُرجع \fI(void\ *)\ \-1\fP، ويُضبط \fIerrno\fP للإشارة إلى الخطأ. .P عند النجاح، يُرجع \fBshmdt\fP() 0؛ عند الخطأ يُرجع \-1، ويتم تعيين \fIerrno\fP للإشارة إلى الخطأ. .SH الأخطاء يمكن أن يفشل \fBshmat\fP() مع أحد الأخطاء التالية: .TP \fBEACCES\fP لا تملك العملية المستدعية الصلاحيات المطلوبة لنوع الربط المطلوب، ولا تملك القدرة \fBCAP_IPC_OWNER\fP في مساحة اسم المستخدم التي تحكم مساحة اسم IPC الخاصة بها. .TP \fBEIDRM\fP يشير \fIshmid\fP إلى معرف مزال. .TP \fBEINVAL\fP قيمة \fIshmid\fP غير صالحة، غير محاذية (أي غير محاذية للصفحة ولم يتم تحديد \fBSHM_RND\fP) أو قيمة \fIshmaddr\fP غير صالحة، أو لا يمكن ربط المقطع عند \fIshmaddr\fP، أو تم تحديد \fBSHM_REMAP\fP وكان \fIshmaddr\fP NULL. .TP \fBENOMEM\fP تعذر تخصيص الذاكرة للوصف أو لجداول الصفحات. .P يمكن أن تفشل \fBshmdt\fP() بأحد الأخطاء التالية: .TP \fBEINVAL\fP .\" The following since Linux 2.6.17-rc1: لا يوجد مقطع ذاكرة مشتركة موصول عند \fIshmaddr\fP؛ أو، \fIshmaddr\fP غير محاذٍ لحدود الصفحة. .SH المعايير POSIX.1\-2008. .SH التاريخ .\" SVr4 documents an additional error condition EMFILE. POSIX.1\-2001، SVr4. .P في SVID 3 (أو ربما أقدم)، تغير نوع الوسيط \fIshmaddr\fP من \fIchar\ *\fP إلى \fIconst void\ *\fP، والنوع المُعاد من \fBshmat\fP() من \fIchar\ *\fP إلى \fIvoid\ *\fP. .P غير POSIX.1\-2024 رمز الخطأ من \fI(void\ *)\ \-1\fP إلى \fBSHM_FAILED\fP. .SH ملاحظات بعد \fBfork\fP(2)، يرث الطفل مقاطع الذاكرة المشتركة الموصولة. .P بعد \fBexecve\fP(2)، تُفصل جميع مقاطع الذاكرة المشتركة الموصولة عن العملية. .P عند \fB_exit\fP(2)، تُفصل جميع مقاطع الذاكرة المشتركة الموصولة عن العملية. .P استخدام \fBshmat\fP() مع \fIshmaddr\fP يساوي NULL هو الطريقة المفضلة والمحمولة لوصل مقطع ذاكرة مشتركة. كن على علم بأن مقطع الذاكرة المشتركة الموصول بهذه الطريقة قد يُوصل بعناوين مختلفة في عمليات مختلفة. لذلك، يجب جعل أي مؤشرات محفوظة داخل الذاكرة المشتركة نسبية (عادةً إلى عنوان بداية المقطع)، بدلاً من مطلقة. .P في لينكس، من الممكن وصل مقطع ذاكرة مشتركة حتى لو كان مُعلماً بالفعل للحذف. ومع ذلك، لا يحدد POSIX.1 هذا السلوك والعديد من التطبيقات الأخرى لا تدعمه. .P المعامل النظامي التالي يؤثر على \fBshmat\fP(): .TP \fBSHMLBA\fP مضاعف عنوان الحد الأدنى للمقطع. عند تحديد عنوان وصل صراحةً في استدعاء لـ \fBshmat\fP()، يجب على المستدعي التأكد من أن العنوان هو مضاعف لهذه القيمة. هذا ضروري في بعض البنى، إما لضمان أداء جيد لذاكرة التخزين المؤقت لوحدة المعالجة المركزية أو لضمان أن وصلات مختلفة لنفس المقطع لها مناظر متسقة داخل ذاكرة التخزين المؤقت لوحدة المعالجة المركزية. \fBSHMLBA\fP عادةً ما يكون مضاعفاً لحجم صفحة النظام. (في العديد من بنى لينكس، \fBSHMLBA\fP هو نفس حجم صفحة النظام.) .P لا يضع التطبيق حداً جوهرياً لكل عملية على عدد مقاطع الذاكرة المشتركة (\fBSHMSEG\fP). .SH أمثلة يتبادل البرنامجان المعروضان أدناه سلسلة نصية باستخدام مقطع ذاكرة مشتركة. تُعطى تفاصيل إضافية حول البرامج أدناه. أولاً، نعرض جلسة شل توضح استخدامهما. .P في نافذة طرفية واحدة، نشغل برنامج "القارئ"، الذي ينشئ مقطع ذاكرة مشتركة من System V ومجموعة إشارة من System V. يطبع البرنامج معرفات الكائنات المنشأة، ثم ينتظر تغير قيمة الإشارة. .P .in +4n .EX $\fB ./svshm_string_read\fP; shmid = 1114194 semid = 15 .EE .in .P في نافذة طرفية أخرى، نشغل برنامج "الكاتب". يأخذ برنامج "الكاتب" ثلاث وسائط لسطر الأوامر: معرفات مقطع الذاكرة المشتركة ومجموعة الإشارة المنشأة بواسطة "القارئ"، وسلسلة نصية. يصل مقطع الذاكرة المشتركة الموجود، وينسخ السلسلة النصية إلى الذاكرة المشتركة، ويعدل قيمة الإشارة. .P .in +4n .EX $\fB ./svshm_string_write 1114194 15 \[aq]Hello, world\[aq]\fP; .EE .in .P بالعودة إلى الطرفية حيث يعمل "القارئ"، نرى أن البرنامج توقف عن الانتظار على الإشارة وطبع السلسلة النصية التي نُسخت إلى مقطع الذاكرة المشتركة بواسطة الكاتب: .P .in +4n .EX Hello, world .EE .in .\" .SS "مصدر البرنامج: svshm_string.h" ملف الرأس التالي مُضمن بواسطة برنامجي "القارئ" و"الكاتب": .P .in +4n .\" SRC BEGIN (svshm_string.h) .EX /* svshm_string.h \& Licensed under GNU General Public License v2 or later. */ #ifndef SVSHM_STRING_H #define SVSHM_STRING_H \& #include #include #include #include \& union semun { /* Used in calls to semctl() */ int val; struct semid_ds *buf; unsigned short *array; #if defined(__linux__) struct seminfo *__buf; #endif }; \& #define MEM_SIZE 4096 \& #endif // include guard .EE .\" SRC END .in .\" .SS "مصدر البرنامج: svshm_string_read.c" ينشئ برنامج "القارئ" مقطع ذاكرة مشتركة ومجموعة إشارة تحتوي على إشارة واحدة. ثم يصل كائن الذاكرة المشتركة إلى مساحة عنوانه ويُهيئ قيمة الإشارة إلى 1. أخيراً، ينتظر البرنامج حتى تصبح قيمة الإشارة 0، وبعد ذلك يطبع السلسلة النصية التي نُسخت إلى مقطع الذاكرة المشتركة بواسطة "الكاتب". .P .in +4n .\" SRC BEGIN (svshm_string_read.c) .EX /* svshm_string_read.c \& Licensed under GNU General Public License v2 or later. */ #include #include #include #include #include #include \& #include "svshm_string.h" \& int main(void) { int semid, shmid; char *addr; union semun arg, dummy; struct sembuf sop; \& /* Create shared memory and semaphore set containing one semaphore. */ \& shmid = shmget(IPC_PRIVATE, MEM_SIZE, IPC_CREAT | 0600); if (shmid == \-1) err(EXIT_FAILURE, "shmget"); \& semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600); if (semid == \-1) err(EXIT_FAILURE, "semget"); \& /* Attach shared memory into our address space. */ \& addr = shmat(shmid, NULL, SHM_RDONLY); if (addr == (void *) \-1) err(EXIT_FAILURE, "shmat"); \& /* Initialize semaphore 0 in set with value 1. */ \& arg.val = 1; if (semctl(semid, 0, SETVAL, arg) == \-1) err(EXIT_FAILURE, "semctl"); \& printf("shmid = %d\[rs]n", shmid); printf("semid = %d\[rs]n", semid); \& /* Wait for semaphore value to become 0. */ \& sop.sem_num = 0; sop.sem_op = 0; sop.sem_flg = 0; \& if (semop(semid, &sop, 1) == \-1) err(EXIT_FAILURE, "semop"); \& /* Print the string from shared memory. */ \& printf("%s\[rs]n", addr); \& /* Remove shared memory and semaphore set. */ \& if (shmctl(shmid, IPC_RMID, NULL) == \-1) err(EXIT_FAILURE, "shmctl"); if (semctl(semid, 0, IPC_RMID, dummy) == \-1) err(EXIT_FAILURE, "semctl"); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .in .\" .SS "مصدر البرنامج: svshm_string_write.c" يأخذ برنامج الكاتب ثلاث وسائط لسطر الأوامر: معرفات مقطع الذاكرة المشتركة ومجموعة الإشارة التي أنشأها "القارئ" بالفعل، وسلسلة نصية. يصل مقطع الذاكرة المشتركة إلى مساحة عنوانه، ثم يُنقص قيمة الإشارة إلى 0 لإعلام "القارئ" بأنه يمكنه الآن فحص محتويات الذاكرة المشتركة. .P .in +4n .\" SRC BEGIN (svshm_string_write.c) .EX /* svshm_string_write.c \& Licensed under GNU General Public License v2 or later. */ #include #include #include #include #include #include \& #include "svshm_string.h" \& int main(int argc, char *argv[]) { int semid, shmid; char *addr; size_t size; struct sembuf sop; \& if (argc != 4) { fprintf(stderr, "Usage: %s shmid semid string\[rs]n", argv[0]); exit(EXIT_FAILURE); } \& size = strlen(argv[3]) + 1; /* +1 to include trailing \[aq]\[rs]0\[aq] */ if (size > MEM_SIZE) { fprintf(stderr, "String is too big!\[rs]n"); exit(EXIT_FAILURE); } \& /* Get object IDs from command\-line. */ \& shmid = atoi(argv[1]); semid = atoi(argv[2]); \& /* Attach shared memory into our address space and copy string (including trailing null byte) into memory. */ \& addr = shmat(shmid, NULL, 0); if (addr == (void *) \-1) err(EXIT_FAILURE, "shmat"); \& memcpy(addr, argv[3], size); \& /* Decrement semaphore to 0. */ \& sop.sem_num = 0; sop.sem_op = \-1; sop.sem_flg = 0; \& if (semop(semid, &sop, 1) == \-1) err(EXIT_FAILURE, "semop"); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .in .SH "انظر أيضًا" \fBbrk\fP(2), \fBmmap\fP(2), \fBshmctl\fP(2), \fBshmget\fP(2), \fBcapabilities\fP(7), \fBshm_overview\fP(7), \fBsysvipc\fP(7) .PP .SH ترجمة تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي . .PP هذه الترجمة هي وثيقة مجانية؛ راجع .UR https://www.gnu.org/licenses/gpl-3.0.html رخصة جنو العامة الإصدار 3 .UE أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات. .PP إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: .MT kde-l10n-ar@kde.org .ME .