در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

IPC چیست؟ معرفی ارتباط بین پردازه ای در لینوکس قسمت 7

4. یک مثال

با استفاده از یکی از روش های IPC، چهار برنامه به گونه ای می نویسیم که:

  1. برنامه اول یک فایل مشخص را باز کرده و محتوای آن را درون IPC بنویسید.
  2. برنامه دوم IPC را خوانده و محتوای آن را پیمایش کرده و به کد اسکی هر کاراکتر 2 واحد اضافه می کند و رشته حاصل را به IPC می فرستد.
  3. برنامه سوم IPC را خوانده و همه حروف کوچک را به حروف بزرگ و همه حروف بزرگ را به حروف کوچک تبدیل می کند.
  4. برنامه ی چهارم IPC را خوانده و در فایلی هم نام با فایل ورودی و با پسوند "output." ذخیره می کند.

برای پیاده سازی این مثال، از تکنیک حافظه اشتراکی استفاده می کنیم.

توجه: در هر چهار برنامه ما یک ساختمان به صورت زیر تعریف کرده و در بدنه برنامه یک شی از آن می سازیم. این شی به حافظ اشتراکی ایجاد شده اشاره خواهد کرد. (در حقیقت محتوای اعضای این ساختمان، همان محتوای حافظه اشتراکی می باشد). به وسیله همین ساختمان ما می توانیم نوعی از همزمانی را نیز پیاده سازی کنیم. در این ساختمان به وسیله turn ، بین پردازه ها همزمانی ایجاد می کنیم و someText هم نشانگر محتوایی است برنامه اول آن را از فایل می خواند و برنامه های بعدی بر روی آن تغیرات اعمال می کنند.

struct shared_space{
	int turn;
	char someText[text_size];
};

توجه: هر جهار برنامه بعد از اتمام کار خود، حافظه اشتراکی را از فضای آدرس خود جدا می کنند. آخرین برنامه، یعنی برنامه چهارم علاوه بر جدا کردن حافظه اشتراکی آن را حذف کرده و فضای اختصاص داده شده به آن را به سیستم برمی گرداند.

برنامه اول

در این برنامه ابتدا باید حافظه اشتراکی ایجاد شود. سایز مورد نیاز برای حافظه اشتراکی همان سایز ساختمان ذکر شده در بالا خواهد بود. این کار به صورت زیر انجام می شود:

shmId=shmget((key_t)6543,sizeof(struct shared_space),0666|IPC_CREAT);

در ادامه باید یک شی از ساختمان shared__space ساخته شود و سپس باید کاری کنیم که این شی به حافظه اشتراکی اشاره کند. این کار به صورت زیر انجام می شود:

struct shared_space *shMem;
shMem=(struct shared_space*)shmAdr;

در پایان باید فایل ورودی را باز کرده، محتوای آن را خوانده و درون حافظه اشتراکی بریزیم. این مراحل به صورت زیر انجام می شوند.

char bf[text_size];
FILE *myFile=fopen("db.txt","r");
fgets(bf,text_size,myFile);
strncpy(shMem->someText,bf,sizeof(shMem->someText));

در ادامه سورس کامل برنامه اول آورده شده است.

#include "unistd.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "sys/shm.h"

#define text_size 2048
struct shared_space{
	int turn;
	char someText[text_size];
};

void main()
{
	int shmId;
	struct shared_space *shMem;
	void* shmAdr=NULL;
	shmId=shmget((key_t)6543,sizeof(struct shared_space),0666|IPC_CREAT);
	if(shmId!=-1)
	{
		printf("prog 1 ::: shared memory id: %d\n",shmId);
		shmAdr=shmat(shmId,NULL,0);
		printf("prog 1 ::: shared memory attached at %X\n",(int)shmAdr);
		shMem=(struct shared_space*)shmAdr;
		shMem->turn=0;
		while(1)
		{
			if(shMem->turn==0)
			{
				char bf[text_size];
				FILE *myFile=fopen("db.txt","r");
				fgets(bf,text_size,myFile);
				printf("prog 1 ::: file content = %s\n",bf);
				strncpy(shMem->someText,bf,sizeof(shMem->someText));
				shMem->turn=1;
				break;
			}
		}
	}
	else
		printf("prog 1 ::: failed to create shared memory\n");
	if(shmdt(shmAdr)!=-1)
		printf("prog 1 ::: shared memory detached\n\n");
	else
		printf("prog 1 ::: failed to delete shared memory\n");
}

برنامه دوم

بیشتر قسمت های این برنامه همانند برنامه اول است، با این تفاوت که در این برنامه باید به محتوای حافظه اشتراکی یا بهتر است بگوییم رشته قرار گرفته در عضو someText از ساختمان shared__space دسترسی پیدا کنیم و به کد اسکی هر کاراکتر 2 واحد اضافه کنیم. این برنامه زمانی اجازه تغییر در حافظه اشتراکی را دارد که مقدار عضو turn از ساختمان shared_space برابر با 1 باشد؛ در غیر این صورت برنامه برای مدت زمان مشخصی به خواب می رود.برای خواندن حافظه اشتراکی، اضافه کردن 2 واحد به کد اسکی هر کاراکتر و اعمال تغییرات به صورت زیر عمل می کنیم:

if(shMem->turn==1)
{
	char temp[text_size];
	strcpy(temp,shMem->someText);	//خواندن حافظه اشتراکی
	int i=0;
	while(1)
	{
		if(i!=strlen(temp))
		{
			temp[i]+=2;	//اضافه کردن 2 واحد به کد اسکی هر کاراکتر
			i++;
		}
		else
			break;
	}
	strcpy(shMem->someText,temp);	//اعمال تغییرات در حافظه اشتراکی
}

در ادامه سورس کامل برنامه دوم آورده شده است (هدر فایل ها و نحوه تعریف ساختمان، مشابه برنامه اول است. به همین جهت در برنامه های آتی، از ذکر دوباره آن خودداری کرده ایم):

void main()
{
	int shmId;
	struct shared_space *shMem;
	void* shmAdr=NULL;

	shmId=shmget((key_t)6543,sizeof(struct shared_space),0666|IPC_CREAT);

	if(shmId!=-1)
	{
		printf("prog 2 ::: shared memory id: %d\n",shmId);
		shmAdr=shmat(shmId,NULL,0);
		printf("prog 2 ::: shared memory attached at %X\n",(int)shmAdr);

		shMem=(struct shared_space*)shmAdr;
		while(1)
		{
			if(shMem->turn==1)
			{
				char temp[text_size];
				strcpy(temp,shMem->someText);
				int i=0;
				while(1)
				{
					if(i!=strlen(temp))
					{
						temp[i]+=2;
						i++;
					}
					else
						break;
				}
				printf("prog 2 ::: shared memory content: %s\n",shMem->someText);				
				strcpy(shMem->someText,temp);
				printf("prog 2 ::: modified shared memory: %s\n",temp);
				shMem->turn=2;
				break;
			}
			else
			{
				srand(time(NULL));
				printf("it's not prog 2's turn\n");
				sleep(1+rand()%10);
			}
		}
	}
	else
		printf("prog 2 ::: failed to create shared memory\n");
	if(shmdt(shmAdr)!=-1)
		printf("prog 2 ::: shared memory detached\n",getpid());
}

برنامه سوم

اسکلت این برنامه نیز مانند برنامه های قبل می باشد، به جز این که در اینجا حروف کوچک را به بزرگ و حروف بزرگ را به کوچک تبدیل می کنیم. اگر کد اسکی بین 64 و 91 باشد یعنی اینکه کاراکتر یک حررف بزرگ است و برای تبدیل کردن آن به حرف کوچک کافی است که 32 واحد به آن اضافه کنیم. اگر کد اسکی بین 96 و 123 باشد یعنی اینکه کاراکتر یک حرف کوچک است و برای تبدیل کردن آن به حرف بزرگ کافی است 32 واحد از آن کم کنیم. لازم به ذکر است که این برنامه زمانی اجازه تغییر در حافظه اشتراکی را دارد که مقدار turn از ساختمان shared__space برابر 2 باشد؛ در غیر اینصورت برنامه برای مدت زمان مشخصی به خواب می رود. در پایان تغییرات صورت گرفته را در حافظه اشتراکی اعمال می کنیم.در زیر کد مورد نیاز برای موارد ذکر شده در بالا آورده شده است:

if(shMem->turn==2)
{
	char temp[text_size];
	strcpy(temp,shMem->someText);	//خواندن حافظه اشتراکی
	int i=0;
	while(1)
	{
		if(i!=strlen(temp))
		{
			if(temp[i]>64&&temp[i]<91)temp[i]+=32;	//تبدیل حروف بزرگ به کوچک
			else if(temp[i]>96&&temp[i]<123)temp[i]-=32;	//تبدیل حروف کوچک به بزرگ
			i++;
		}
		else
			break;
	}
	strcpy(shMem->someText,temp);	//اعمال تغییرات در حافظه اشتراکی
}

در ادامه سورس برنامه سوم به صورت کامل آورده شده است.

void main()
{

	int shmId;
	struct shared_space *shMem;
	void* shmAdr=NULL;

	shmId=shmget((key_t)6543,sizeof(struct shared_space),0666|IPC_CREAT);

	if(shmId!=-1)
	{
		printf("prog 3 ::: shared memory id: %d\n",shmId);
		shmAdr=shmat(shmId,NULL,0);
		printf("prog 3 ::: shared memory attached at %X\n",(int)shmAdr);

		shMem=(struct shared_space*)shmAdr;
		while(1)
		{
			if(shMem->turn==2)
			{
				char temp[text_size];
				strcpy(temp,shMem->someText);
				int i=0;
				while(1)
				{
					if(i!=strlen(temp))
					{
						if(temp[i]>64&&temp[i]<91)temp[i]+=32;
						else if(temp[i]>96&&temp[i]<123)temp[i]-=32;
						i++;
					}
					else
						break;
				}
				printf("prog 3 ::: shared memory content: %s\n",shMem->someText);
				printf("prog 3 ::: modified shared memory: %s\n",temp);
				strcpy(shMem->someText,temp);
				shMem->turn=3;
				break;
			}
			else
			{
				srand(time(NULL));
				printf("it's not prog 3's turn\n");
				sleep(1+rand()%10);
			}
		}
	}
	else
		printf("prog 3 ::: failed to create shared memory\n");
	if(shmdt(shmAdr)!=-1)
		printf("prog 3 ::: shared memory detached\n",getpid());
}

برنامه چهارم

وظیفه این برنامه تنها خواندن حافظه اشتراکی و نوشتن محتوای آن در یک فایل با پسوند "output." است. در اینجا منظور از محتوای حافظه اشتراکی همان رشته قرار گرفته در عضو someText از ساختمان shared__space می باشد. البته برنامه زمانی که مقدار turn برابر با 3 باشد اجازه نوشتن در فایل را پیدا می کند.این کار به صورت زیر انجام می شود.

if(shMem->turn==3)
{
	char bf[text_size];
	strncpy(bf,shMem->someText,sizeof(shMem->someText));	//خواندن محتوای حافظه اشتراکی
	FILE *myFile=fopen("db.output","w");	  //باز کردن یک فایل (در صورت عدم وجود ایجاد یک فایل جدید)
	fputs(bf,myFile);		//نوشتن محتوای حافظه اشتراکی در فایل
}

در ادامه سورس کامل برنامه چهارم آورده شده است.

void main()
{
	int shmId;
	struct shared_space *shMem;
	void* shmAdr=NULL;

	shmId=shmget((key_t)6543,sizeof(struct shared_space),0666|IPC_CREAT);

	if(shmId!=-1)
	{
		printf("prog 4 ::: shared memory id: %d\n",shmId);
		shmAdr=shmat(shmId,NULL,0);
		printf("prog 4 ::: shared memory attached at %X\n",(int)shmAdr);

		shMem=(struct shared_space*)shmAdr;
		while(1)
		{
			if(shMem->turn==3)
			{
				char bf[text_size];
				strncpy(bf,shMem->someText,sizeof(shMem->someText));
				printf("prog 4 ::: (write to a file) shared memory content = %s\n",bf);

				FILE *myFile=fopen("db.output","w");
				fputs(bf,myFile);
				//shMem->turn=1;
				break;
		}
	}
}
	else
		printf("prog 4 ::: failed to create shared memory\n");
	if(shmdt(shmAdr)!=-1)
		printf("prog 4 ::: shared memory detached\n",getpid());
	if(shmctl(shmId,IPC_RMID,0)!=-1)
		printf("prog 4 ::: shared memory deleted...\n\n");
	else
		printf("prog 4 ::: failed to delete shared memory\n");
}

نمونه اجرای برنامه

وب سایت توسینسو
عنوان
1 IPC چیست؟ معرفی ارتباط بین پردازه ای در لینوکس قسمت 1 رایگان
2 IPC چیست؟ معرفی ارتباط بین پردازه ای در لینوکس قسمت 2 رایگان
3 IPC چیست؟ معرفی ارتباط بین پردازه ای در لینوکس قسمت 3 رایگان
4 IPC چیست؟ معرفی ارتباط بین پردازه ای در لینوکس قسمت 4 رایگان
5 IPC چیست؟ معرفی ارتباط بین پردازه ای در لینوکس قسمت 5 رایگان
6 IPC چیست؟ معرفی ارتباط بین پردازه ای در لینوکس قسمت 6 رایگان
7 IPC چیست؟ معرفی ارتباط بین پردازه ای در لینوکس قسمت 7 رایگان
زمان و قیمت کل 0″ 0
0 نظر

هیچ نظری ارسال نشده است! اولین نظر برای این مطلب را شما ارسال کنید...

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره پاییزه می تونی امروز ارزونتر از فردا خرید کنی ....