- unstable 4.31.0-1
| makecontext(3) | Library Functions Manual | makecontext(3) |
الاسم¶
makecontext, swapcontext - معالجة سياق المستخدم
المكتبة¶
مكتبة سي المعيارية (libc، -lc)
موجز¶
#include <ucontext.h>
void makecontext(ucontext_t *ucp, typeof(void (int arg0, ...)) *func,
int argc, ...);
int swapcontext(ucontext_t *restrict oucp,
const ucontext_t *restrict ucp);
الوصف¶
في بيئة شبيهة بـ System V، يوجد النوع ucontext_t (المُعرَّف في <ucontext.h> والموصوف في getcontext(3)) والدوال الأربع getcontext(3) وsetcontext(3) وmakecontext() وswapcontext() التي تسمح بتبديل السياق على مستوى المستخدم بين خيوط تحكم متعددة داخل عملية.
تعدّل الدالة makecontext() السياق المُشار إليه بواسطة ucp (الذي حُصِل عليه من استدعاء getcontext(3)). قبل استدعاء makecontext()، يجب على المستدعي تخصيص مكدس جديد لهذا السياق وتعيين عنوانه إلى ucp->uc_stack، وتعريف سياق خلف وتعيين عنوانه إلى ucp->uc_link.
عند تفعيل هذا السياق لاحقًا (باستخدام setcontext(3) أو swapcontext())، تُستدعى الدالة func وتُمرَّر إليها سلسلة وسائط الأعداد الصحيحة (int) التي تلي argc؛ يجب على المستدعي تحديد عدد هذه الوسائط في argc. عند عودة هذه الدالة، يُفعَّل السياق الخلف. إذا كان مؤشر السياق الخلف NULL، يخرج الخيط.
تحفظ الدالة swapcontext() السياق الحالي في البنية المُشار إليها بواسطة oucp، ثم تُفعِّل السياق المُشار إليه بواسطة ucp.
قيمة الإرجاع¶
عند النجاح، لا تعود swapcontext(). (لكن قد نعود لاحقًا، في حالة تفعيل oucp، حيث يبدو أن swapcontext() تعيد 0.) عند الخطأ، تعيد swapcontext() -1 وتضبط errno للإشارة إلى الخطأ.
الأخطاء¶
- ENOMEM
- مساحة مكدس متبقية غير كافية.
السمات¶
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
| الواجهة | السمة | القيمة |
| makecontext() | سلامة الخيوط | آمن للمسارات المتعددة (MT-Safe) سباق:ucp |
| swapcontext() | سلامة الخيوط | MT-Safe race:oucp race:ucp |
المعايير¶
لا شيء.
التاريخ¶
glibc 2.1. SUSv2, POSIX.1-2001. أُزيل في POSIX.1-2008، مستشهدًا بمشاكل قابلية النقل، ويوصي بإعادة كتابة التطبيقات لاستخدام خيوط POSIX بدلاً من ذلك.
ملاحظات¶
تفسير ucp->uc_stack هو تمامًا كما في sigaltstack(2)، أي أن هذه البنية تحتوي على بداية وطول منطقة ذاكرة لتُستخدم كمكدس، بغض النظر عن اتجاه نمو المكدس. وبالتالي، ليس من الضروري لبرنامج المستخدم القلق بشأن هذا الاتجاه.
في البنى حيث int وأنواع المؤشرات بنفس الحجم (مثل x86-32، حيث كلا النوعين 32 بت)، قد تتمكن من تمرير المؤشرات كوسائط إلى makecontext() بعد argc. لكن، القيام بذلك غير مضمون ليكون محمولاً، وهو غير مُعرَّف وفقًا للمعايير، ولن يعمل في البنى حيث المؤشرات أكبر من int. ومع ذلك، بدءًا من glibc 2.8، أجرت glibc بعض التغييرات على makecontext() للسماح بذلك في بعض البنى 64 بت (مثل x86-64).
أمثلة¶
يوضح برنامج المثال أدناه استخدام getcontext(3) وmakecontext() وswapcontext(). يؤدي تشغيل البرنامج إلى إخراج التالي:
$ ./a.out main: swapcontext(&uctx_main, &uctx_func2) func2: started func2: swapcontext(&uctx_func2, &uctx_func1) func1: started func1: swapcontext(&uctx_func1, &uctx_func2) func2: returning func1: returning main: exiting
مصدر البرنامج¶
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
static ucontext_t uctx_main, uctx_func1, uctx_func2;
static void
func1(void)
{
printf("%s: started\n", __func__);
printf("%s: swapcontext(&uctx_func1, &uctx_func2)\n", __func__);
if (swapcontext(&uctx_func1, &uctx_func2) == -1)
err(EXIT_FAILURE, "swapcontext");
printf("%s: returning\n", __func__);
}
static void
func2(void)
{
printf("%s: started\n", __func__);
printf("%s: swapcontext(&uctx_func2, &uctx_func1)\n", __func__);
if (swapcontext(&uctx_func2, &uctx_func1) == -1)
err(EXIT_FAILURE, "swapcontext");
printf("%s: returning\n", __func__);
}
int
main(int argc, char *argv[])
{
char func1_stack[16384];
char func2_stack[16384];
if (getcontext(&uctx_func1) == -1)
err(EXIT_FAILURE, "getcontext");
uctx_func1.uc_stack.ss_sp = func1_stack;
uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
uctx_func1.uc_link = &uctx_main;
makecontext(&uctx_func1, func1, 0);
if (getcontext(&uctx_func2) == -1)
err(EXIT_FAILURE, "getcontext");
uctx_func2.uc_stack.ss_sp = func2_stack;
uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
/* Successor context is f1(), unless argc > 1 */
uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
makecontext(&uctx_func2, func2, 0);
printf("%s: swapcontext(&uctx_main, &uctx_func2)\n", __func__);
if (swapcontext(&uctx_main, &uctx_func2) == -1)
err(EXIT_FAILURE, "swapcontext");
printf("%s: exiting\n", __func__);
exit(EXIT_SUCCESS);
}
انظر أيضًا¶
sigaction(2), sigaltstack(2), sigprocmask(2), getcontext(3), sigsetjmp(3)
ترجمة¶
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>
هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.
إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.
| 8 فبراير 2026 | صفحات دليل لينكس 6.18 |