Эгзэгтэй муж

Олон програм зэрэг хамтран ажиллах үед тэдгээрийн дунд ашиглагдаж буй мэдээлэл, төхөөрөмж зэрэгт нэг дор олон хандалт үүсгэхгүй байх үүднээс эгзэгтэй мужийн асуудал яригддаг. Өөрөөр хэлбэл процессууд дундаа ашигладаг функц, хүснэгт зэрэгт хандсан тухайн процессын өөрийнх нь кодын хэсгийг эгзэгтэй муж гэнэ. Тухайн эгзэгтэй муж нь тодорхой хугацаанд нээгдэж, хаагдах ба түүнд хандахыг хүссэн процесс, таск зэрэг нь хүсэлт үлдээн хэсэг хугацаанд хүлээлтийн горимд ордог. Иймээс процесс эсвэл таск нь эгзэгтэй мужид орж гарч байгааг зохицуулах механизмууд бий болжээ. Жишээ нь Семафор.

Эгзэгтэй мужийн асуудал[засварлах | кодоор засварлах]

N тооны процессоос тогтсон систем байна гэж төсөөл. {P0, P1, P2.... Pn-1 г.м} Процесс бүрт эгзэгтэй муж гэж байх ба тэр хэсэг нь уг процессуудын дундын эзэмшлийн хувьсагч, хүснэгт, аль эсвэл өгөгдлийг өөрчилдөг гэж үзье. Зэрэг хандалт хийгдэх үед маш том асуудал үүсэх учраас үйлдлийн системийн гол үүрэг бол эгзэгтэй мужид нэг дор нэгээс олон процесс оруулахгүй байх явдал. Энэ асуудлыг шийдэхийн тулд процессуудыг хамтран ажилуулж чадахуйц нь зохицуулах механизм боловсруулах хэрэгтэй. Процесс болгон эгзэгтэй муж руу орохын өмнө хүсэлт явуулдаг байх ёстой. Механизмын энэ хэсгийг хэрэгжүүлж буй кодыг оролтын хэсэг гэнэ. Хүсэлт явуулж зөвшөөрөл авсны үндсэн дээр эгзэгтэй мужид нэвтэрсэн процесс гаралтын кодын хэсэгт дуусна. Үлдсэн бусад кодыг үлдэгдэл хэсэг гэнэ.[1]

Онол(ерөнхий)[засварлах | кодоор засварлах]

Процесс болгон эгзэгтэй муж руу орохын өмнө хүсэлт явуулдаг байх ёстой. Механизмын энэ хэсгийг хэрэгжүүлж буй кодыг оролтын хэсэг гэнэ. Хүсэлт явуулж зөвшөөрөл авсны үндсэн дээр эгзэгтэй мужид нэвтэрсэн процесс гаралтын кодын хэсэгт дуусна. Үлдсэн бусад кодыг үлдэгдэл хэсэг гэнэ. Зэрэг хандалт хийгдэх үед маш том асуудал үүсэх учраас үйлдлийн системийн гол үүрэг бол эгзэгтэй мужид нэг дор нэгээс олон процесс оруулахгүй байх явдал. Энэ асуудлыг шийдэхийн тулд процессуудыг хамтран ажилуулж чадахуйц нь зохицуулах механизм боловсруулах хэрэгтэй. Процесс болгон эгзэгтэй муж руу орохын өмнө хүсэлт явуулдаг байх ёстой. Механизмын энэ хэсгийг хэрэгжүүлж буй кодыг оролтын хэсэг гэнэ.

Эгзэгтэй мужийн асуудлыг шийдэхийн тулд дараах шаардлагуудыг хангасан байх шаардлагатай. 1. Давхар нэвтрэлтийг хорих (Mutual exclusion) Хэрэв нэг процесс эгзэгтэй мужид нэвтэрсэн бол өөр процесс үл нэвтрүүлэх 2. Явцыг дэмжих (progress) Өөр ямар ч процессд эгзэгтэй муж үүсээгүй байхад процесс түүнийг хүлээх ёсгүй. 3. Дамжсан хүлээлт (bounded waiting) Процесс тодорхой хугацаанд л эгзэгтэй мужид байх ёстой.

Fig 2: Locks and critical sections in multiple threads

Эгзэгтэй муж талаар ойлголт[засварлах | кодоор засварлах]

Process A:

// Process A
 .
 .
 b = x+5;                 // instruction executes at time = Tx
 .

Process B:

// Process B
.
.
x = 3+z;                 // instruction executes at time = Tx
.
Fig 1: Flow graph depicting need for critical section

Аппликэйшн түвшний эгзэгтэй муж[засварлах | кодоор засварлах]

Аппликэйшн түвшний эгзэгтэй муж нь ихэвчлэн санах ойн тухайн хэсгийг аль процесс эзллэх тухайд яригддаг.

POSIX pthread санд эгзэгтэй мужийг шийдэх жишээ код

/* C/C++ Жишээ, Unix/Linux */
#include <pthread.h>

/* Энэ бол эгзэгтэй муж объект (тогтмолоор өгөгдсөн). */
static pthread_mutex_t cs_mutex = PTHREAD_MUTEX_INITIALIZER;

void f()
{
    /* Эгзэгтэй мужид орох хэсэг -- Бусад процессүүд цоожлогдоно */
    pthread_mutex_lock( &cs_mutex );
 
    /* Энэ хэсэгт бусад процессуудаас хамааралгүй аюулгүй тооцоолол хийгдэнэ! */

    /*Эгзэгтэй мужаас гарах хэсэг -- бусад процессүүд эгзэгтэйи мужид орох эрхтэй болно. pthread_mutex_lock()  */
    pthread_mutex_unlock( &cs_mutex );
}

int main()
{
    f();

    return 0;
}

Win32 API санд эгзэгтэй мужийг шийдэх жишээ код

/* C/C++ жишээ, Windows */
#include <windows.h>

static CRITICAL_SECTION cs; /* Эгзэгтэй муж объект үүссэний дараа санах ойд зөөж шилжүүлэх боломжгүй */
                            /* объект хандалтат хэл дээр тогтмолоор зарлахгүй байж болно */ 
void f()
{
    /* Эгзэгтэй мужид орох хэсэг -- Бусад процессүүд цоожлогдоно */
    EnterCriticalSection(&cs);

     /* Энэ хэсэгт бусад процессуудаас хамааралгүй аюулгүй тооцоолол хийгдэнэ! */

   /*Эгзэгтэй мужаас гарах хэсэг -- бусад процессүүд эгзэгтэйи мужид орох эрхтэй болно. pthread_mutex_lock()  */
    LeaveCriticalSection(&cs);
}

int main()
{
    /* Олон процесс ашиглах үйлдэл хийгдэхээс өмнө эгзэгтэй муж объект үүсгэнэ */
    InitializeCriticalSection(&cs);

    f(); 

    /* Дуусмагц объектыг арилгана */
    DeleteCriticalSection(&cs);

    return 0;
}

Кернелийн түвшиний эгзэгтэй муж[засварлах | кодоор засварлах]

Кернелийн түвшинд эгзэгтэй муж нь процессууд болон хуулбар процессууд хоорондоо зөрчилдөлгүй ажиллах боломжыг хангаж өгдөг.

Зарим үйлдлийн систем нэг зэрэг олон эгзэгтэй муж /холбоотой процессууд бүрт нэг/ үүсгэж ажилладаг.

Диспетчер нь процессуудыг хооронд нь зохицуулах ба эгзэгтэй мужид байгаа процессыг дараа биелүүлэхээр түр зогсоох эсвэл эгзэгтэй мужаас гартал нь хүлээсний дараа дараагын процессд эгзэгтэй муж олгох зэргийг хариуцна.

Fig 2: Locks and critical sections in multiple threads
Fig 3: Pseudo code for implementing critical section

Эгзэгтэй мужийн төвшин[засварлах | кодоор засварлах]

Кернелийн түвшинд эгзэгтэй муж нь процессууд болон хуулбар процессууд хоорондоо зөрчилдөлгүй ажиллах боломжыг хангаж өгдөг. Зарим үйлдлийн систем нэг зэрэг олон эгзэгтэй муж /холбоотой процессууд бүрт нэг/ үүсгэж ажилладаг.

Диспетчер нь процессуудыг хооронд нь зохицуулах ба эгзэгтэй мужид байгаа процессыг дараа биелүүлэхээр түр зогсоох эсвэл эгзэгтэй мужаас гартал нь хүлээсний дараа дараагын процессд эгзэгтэй муж олгох зэргийг хариуцна. Кернелийн төвшин гэж байдаг бөгөөд кернелийн түвшний эгзэгтэй муж нь процессууд болон хуулбар процессууд хоорондоо зөрчилдөлгүй ажиллах боломжыг хангаж өгдөг.Зарим үйлдлийн систем нэг зэрэг олон эгзэгтэй муж /холбоотой процессууд бүрт нэг/ үүсгэж ажилладаг. Диспетчер нь процессуудыг хооронд нь зохицуулах ба эгзэгтэй мужид байгаа процессыг дараа биелүүлэхээр түр зогсоох эсвэл эгзэгтэй мужаас гартал нь хүлээсний дараа дараагын процессд эгзэгтэй муж олгох зэргийг хариуцна. Гүйцэтгэлийн өргөжүүлэлт нь бүх чухал хэсгүүд нь гарах үед хүлээгдэж тасалдлуудыг гүйцэтгэх болон хуваарилагчийн бүх чухал хэсгүүд нь гарах ажиллуулах боломжийг олгодог. Чухал хэсэг нь урт хугацааны түгжих бааз болгон ашиглаж болохгүй.Mиймээс энэ нь хангалттай хуваарилагч-аас гарч ямар ч тасалдлууд ч гарсан техник хангамж гүйцэтгэсэн байх ёстой.

Эгзэгтэй муж өгөгдлийн бүтэц онцлох хэсэг[засварлах | кодоор засварлах]

Зэрэгцээ програмчлал онд код сэдвээр хуваагддаг.Процесс болгон эгзэгтэй муж руу орохын өмнө хүсэлт явуулдаг байх ёстой. Механизмын энэ хэсгийг хэрэгжүүлж буй кодыг оролтын хэсэг гэнэ. Хүсэлт явуулж зөвшөөрөл авсны үндсэн дээр эгзэгтэй мужид нэвтэрсэн процесс гаралтын кодын хэсэгт дуусна. Үлдсэн бусад кодыг үлдэгдэл хэсэг гэнэ. Эгзэгтэй мужийн асуудлыг шийдэхийн тулд дараах шаардлагуудыг хангасан байх шаардлагатай. 1. Давхар нэвтрэлтийг хорих (Mutual exclusion) Хэрэв нэг процесс эгзэгтэй мужид нэвтэрсэн бол өөр процесс үл нэвтрүүлэх 2. Явцыг дэмжих (progress) Өөр ямар ч процессд эгзэгтэй муж үүсээгүй байхад процесс түүнийг хүлээх ёсгүй. 3. Дамжсан хүлээлт (bounded waiting) Процесс тодорхой хугацаанд л эгзэгтэй мужид байх ёстой.Зэрэгцээгээр хооронд хувааж чадахгүй байгаа өгөгдлийгхэрэгжүүлэх хувьсагч нь улмаар маш хэцүү байдаг байх.Элементийг хайж утас зүгээр л тодорхой хугацааны дараа түүнийг устгаж болно. Код нь хүлээгдэж буй үр дүнг үзүүлдэг болохыг баталгаажуулдаг

Эх сурвалж[засварлах | кодоор засварлах]

  1. [1]Operating System Concepts - 7th edition, Page 302-303