"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > ضياء ه - فهم السياقات في C

ضياء ه - فهم السياقات في C

تم النشر بتاريخ 2024-10-31
تصفح:331

Dia e - Entendendo contextos em C

في لغة C، السياق هو حالة التنفيذ الحالية للبرنامج، بما في ذلك السجلات (مناطق تخزين صغيرة داخل وحدة المعالجة المركزية، تستخدم لتخزين البيانات والتعليمات أثناء تنفيذ البرنامج)، والمتغيرات والتدفق من التعليمات، الحاسمة لتبديل المهام.

تبديل السياق لأنظمة التشغيل

الوظيفة الرئيسية هي السماح بتعدد المهام. وهذا يضمن أن النظام يمكنه التبديل بين العمليات بكفاءة.

تم توفير ملف contexts.c هنا. إنه عرض لكيفية عمل السياقات.

مباشرة في الجزء العلوي من هذا الملف، نلاحظ استيراد مكتبة ucontext.h. يسمح لك بمعالجة سياق التنفيذ.

في المقتطف أدناه نرى أنه تم إنشاء 3 سياقات، وستكون لهذه السياقات الثلاثة ذاكرة مخصصة بحجم STACKSIZE.

#define STACKSIZE 64 * 1024 /* tamanho de pilha das threads */

ucontext_t ContextPing, ContextPong, ContextMain;

وبعد فترة وجيزة، وظائف Ping وPong التي سيتم تنفيذها في سياقاتها الخاصة:

void BodyPing(void *arg)
{
  int i;

  printf("%s: inicio\n", (char *)arg);

  for (i = 0; i 



في الوظيفة الرئيسية، يتم استخدام malloc لحجز الأكوام، حيث يتم تعيينها لاحقًا باستخدام uc_stack.ss_sp إلى السياق، ويتم استخدام SwapContext للتبديل بينها.

int main(int argc, char *argv[])
{
  char *stack;

  printf("main: inicio\n");

  getcontext(&ContextPing);

  stack = malloc(STACKSIZE);
  if (stack)
  {
    ContextPing.uc_stack.ss_sp = stack;
    ContextPing.uc_stack.ss_size = STACKSIZE;
    ContextPing.uc_stack.ss_flags = 0;
    ContextPing.uc_link = 0;
  }
  else
  {
    perror("Erro na criação da pilha: ");
    exit(1);
  }

  makecontext(&ContextPing, (void *)(*BodyPing), 1, "    Ping");

  getcontext(&ContextPong);

  stack = malloc(STACKSIZE);
  if (stack)
  {
    ContextPong.uc_stack.ss_sp = stack;
    ContextPong.uc_stack.ss_size = STACKSIZE;
    ContextPong.uc_stack.ss_flags = 0;
    ContextPong.uc_link = 0;
  }
  else
  {
    perror("Erro na criação da pilha: ");
    exit(1);
  }

  makecontext(&ContextPong, (void *)(*BodyPong), 1, "        Pong");

  swapcontext(&ContextMain, &ContextPing);
  swapcontext(&ContextMain, &ContextPong);

  printf("main: fim\n");

  exit(0);
}

مخرجات البرنامج المنفذ:

main: inicio
    Ping: inicio
    Ping: 0
        Pong: inicio
        Pong: 0
    Ping: 1
        Pong: 1
    Ping: 2
        Pong: 2
    Ping: 3
        Pong: 3
    Ping: fim
        Pong: fim
main: fim

مع هذا، يمكننا أن نرى أنه حتى عند تغيير السياقات، يتم الحفاظ على القيم التي "تتدفق" عبر الوظيفة، مثال في هذه الحالة هو الفهرس.

ربما لاحظتم وجود Malloc لسياق Ping و Pong، لكننا نرى أن هناك سياقًا لـ main أيضًا، لماذا لا يوجد Malloc له؟

لا يحتاجContextMain إلى مكدس منفصل لأنه يعمل على مكدس الخيط الرئيسي، في حين أن سياقات Ping وPong لها مكدساتها المخصصة ديناميكيًا.

إذا قمت بإنشاء سياق ولم أخصص له ذاكرة، فعندما نستخدم المبادلة، فإنه ينتقل إلى المكدس الرئيسي للبرنامج.

هذا الكود من البروفيسور مازييرو، الموجود في المشروع الفرعي المطور لـ PingPongOS "Trocas de contexto".

بيان الافراج تم نشر هذه المقالة على: https://dev.to/matheusgb/dia-21-e-21-entendo-contextos-em-c-2imm إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3