الى خبراء لينكس ارجوكم المساعدة العاجلة

هنا توجد كل المواضيع المتعلقة بالبرمجيات المفتوحة المصدر

المشرف: Karam

الى خبراء لينكس ارجوكم المساعدة العاجلة

مشاركة غير مقروءةبواسطة khmix » السبت مايو 26, 2012 9:23 pm

كتابة برنامج بلغة c باستخدام استدعاءات نظام لينكس لحل مسألة عشاء الفلاسفة باستخدام السيمافورات لحل مشكلة تزامن الاجرائيات ضمن نظام لينكس.
الأوامر والاستدعاءات :
fork() , getpid(), semget() , semop() , semctl()

مسألة عشاء الفلاسفة تنص على مايلي:
يجلس خمسة فلاسفة في حلقة حول طاولة, عليها 4 كراسي وأمام كل منها طبق لا ينتهي محتواه، وهناك شوكة بين كل صحنين، أي أن أمام كل فيلسوف شوكتان: واحدة على يمينه وأخرى على يساره.
يقضي الفيلسوف حياته في التفكير وتناول الطعام من الطبق ، وليتمكن من تناول الطعام يحتاج إلى تناول الشوكتين ليتمكن من الأكل. وبعد الانتهاء من الأكل، ينظف الفيلسوف الشوكتين ويعيدهما إلى مكانهما جاهزتين للاستخدام من جديد .

اكتب برنامج يقوم بما يلي:

حل المسألة ل 5 فلاسفة و4 كراسي خمسة شوك.
استخدم السيمافورات , بشرط أن يجلس الفيلسوف قبل طلب الشوكة و الأكل .
اكتب تقرير توضح به خوارزمية الحل و عمل البرنامج .



لقد كتبت بكل خبرتي بالسيمافورات ولكن لم استطع الحل بالشكل الكامل فيمكنك بحكم خبرتك :
<تعدل الملف البرمجي التالي لتتحقق الطلبات التي في الاعلى>




CODE: تحديد الكل

#include<errno.h>

#include<math.h>

#include<signal.h>

#include<stdio.h>

#include<stdlib.h>


#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

#include<sys/time.h>


#define FALSE 0

#define TRUE 1

#define NPHIL 4 //عدد الفلاسفة يعدل الى خمسة

#define NCHOPSTICKS NPHIL //عدد الشوك هو نفس عدد الفلاسفة

#define AVG_THINK 2.5 // زمن التفكير بدون أكل حالة الانتظار

#define AVG_EAT 1.5 //زمن الاكل حالة العمل

#define DURATION 30 //الزمن الذي تحدث بعده المقاطعة



typedef union semun{

int val; //حقل لتاسيس السيمافور على الصفر او الواحد

struct semid_ds *buf;

ushort *array;

}SEM_UNION;






static int alarm_flag=FALSE;



/*------print error mesage and terminate a process------*/


void error(const char *msg)
{
fflush(stdout);

printf( "%s %d %s\n", msg ,errno,strerror(errno));

exit(0);
}

/*******signal the semaphore*******/



void my_signal(int s)//التابع الذي يعمل عملية السيغنل
//نمرر له رقم السيمافور الذي اريد ان اعمل عليه سغنل
{

int status;


struct sembuf sb;
sb.sem_num=0;//السيمافور الاول بالمصفوفة
sb.sem_op=1;//رفع )سيغنال
sb.sem_flg=SEM_UNDO;//عندما تجد مشكلةمثل بطئ الكومبيوتر) حرر السيمافور

status=semop(s,&sb,1);//s=semid
if(status<0)
{ error("In my wait,semaphore failed");}
}


/********wait on semaphore*******/
void my_wait(int s)
{
int status;
struct sembuf sb;
sb.sem_num=0;
sb.sem_op=-1;//wait1
sb.sem_flg=SEM_UNDO;

status=semop(s,&sb,1);
if(status<0)
{ error("In my wait,semaphore failed");}
}


/********think *******///خارج المعالج

void think(int phil)//نمرر له رقم الفيلسوف
{
int duration=drand48()*1000000.0*AVG_THINK;//للتحويل الى ميكرو ثانية
printf("phil %d (proc %d) thinking %d microseconds\n",phil,getpid(), duration);
usleep(duration);
}

void eat(int phil)//داخل المعالج
{
int duration=drand48()*1000000.0*AVG_EAT;
printf("phil %d (proc %d) eating %d microseconds\n",phil,getpid(), duration);
usleep(duration);
}


/*****timer*****/

void alarm_handler(sig,code,scp)

int sig;

int code;

struct sigcontext *scp;

{

alarm_flag=TRUE;

}



void set_sig_handler()

{
struct sigaction act;
act.sa_handler=alarm_handler;

#if defined_FreeBSD_
act.sa_mask=0;


#endif
act.sa_flags=SA_RESTART|SA_RESETHAND;

sigaction(SIGUSR1, &act,(struct sigaction *) NULL);

}




/******creat process*********/


int create_philososphers(const int n,int child[])//تابع انشاء الاجرائيات حيث نولد اجراء اب وهو سيولد اربع اجرائيات وجميع الاجرائيات تمثل الفلاسفة
{ //n=5

int i,status;
for (i=0;i<n;++i)
{

child[i]=0;

}

printf("creating %d philosophers\n",n);


for(i=0;i<n;++i)

{

status=fork();
if(status<0)

{
error("failed to creat philosopher \n");}

else if(status==0)//نحن بالابن رجع ابناء
{return i-1;
}
else{ child[i-1]=status;}//نحنبالاب خزن بيايدي للابن pid
}
return -1;
}



/**********Main program*********/

int main( int argc,char *argv[])
{
int child[NPHIL],
chopstick[NCHOPSTICKS],i,status, philosopher_id=0 , left,right;//الشوكة اليمين واليسار
SEM_UNION arg;//لتاسيس السيمافور//from union
key_t k;//لربط السيمافورات
for(i=0;i<=NCHOPSTICKS;++i)
{
k=ftok(argv[0],i);//لتوليد الكي لخمس سيمافورات الشوك
printf("\n",argv[0],k);
chopstick[i]=semget(k,1,IPC_CREAT);//1 لكل شوكة سيمافور وحيد//IPC_CREAT becouse creat new key !!!
printf("chopstick[%d] is %d\n",i,chopstick[i]);



if(chopstick[i]<0)

{error("bad sem creat");
}



arg.val=1;//نأسس السيمافورات على قيمة 1

status=semctl(chopstick[i],0,SETVAL,arg);
if(status<0)
{error("couldnt itinalize sem counter to 1");}
}

/*********creat semaphores******/

philosopher_id=create_philososphers(NPHIL,child);

if(philosopher_id==-1)
{
sleep(DURATION);
for(i=0;i<NPHIL;++i)
{
kill(child[i],SIGUSR1);
}
for(i=0;i<NPHIL;++i)
{
status=wait((int *)0);
if(status<0)
{
error("wait erorr detected");
}
}
for(i=0;i<NCHOPSTICKS;i++)
{
status=semctl(chopstick[i],0,IPC_RMID,0);
if(status<0)
{error("bad remove sem");}
}
}
else
{
left=philosopher_id;
right=(philosopher_id +1)%NPHIL;

set_sig_handler();
while(!alarm_flag)
{
think(philosopher_id);
if(philosopher_id & 0x1)
{
my_wait(chopstick[left]);
printf("phil %d picked up left chopstick %d\n",philosopher_id,getpid(),left);
my_wait(chopstick[right]);
printf("phil %d picked up right chopstick %d\n",philosopher_id,getpid(),right);
}
else
{
my_wait(chopstick[right]);
printf("phil %d picked up right chopstick %d\n",philosopher_id,getpid(),right);
my_wait(chopstick[left]);
printf("phil %d picked up left chopstick %d\n",philosopher_id,getpid(),left);
}

eat(philosopher_id);
if(philosopher_id & 0x1)
{
my_signal(chopstick[left]);
printf("phil %d put down left chopstick %d\n",philosopher_id,getpid(),left);
my_signal(chopstick[right]);
printf("phil %d put down right chopstick %d\n",philosopher_id,getpid(),right);
}
else
{
my_signal(chopstick[right]);
printf("phil %d put down right chopstick %d\n",philosopher_id,getpid(),right);
my_signal(chopstick[left]);
printf("phil %d put down left chopstick %d\n",philosopher_id,getpid(),left);
}
}
}
}
khmix
عضو جديد
عضو جديد
 
مشاركات: 3
اشترك في: السبت مايو 26, 2012 6:24 pm
الجتس: ذكر
الشهادة الثانوية: سورية
الجامعة: جامعة دمشق
الكلية: الهندسة المعلوماتية
المرحلة الدراسية: غير ذلك
الاختصاص: هندسة برمجيات

Re: الى خبراء لينكس ارجوكم المساعدة العاجلة

مشاركة غير مقروءةبواسطة sportit2 » الثلاثاء ديسمبر 03, 2013 11:14 am

جزاكم الله خيرا على هذه المعلومات القيمه
sportit2
عضو جديد
عضو جديد
 
مشاركات: 3
اشترك في: الثلاثاء ديسمبر 03, 2013 11:09 am
الجتس: أنثى
الشهادة الثانوية: مصريه
الجامعة: جامعة بنها
الكلية: الهندسة المعلوماتية
المرحلة الدراسية: ماجستير
الاختصاص: هندسة برمجيات


العودة إلى منتدى البرمجيات المفتوحة المصدر

الموجودون الآن

المستخدمون المتصفحون لهذا المنتدى: لا يوجد أعضاء مسجلين متصلين و 1 زائر