Tải bản đầy đủ (.docx) (7 trang)

báo cáo thực hành chương trình giao tiếp giữa hai tiến trình bằng cách sử dụng shared memory

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (164.59 KB, 7 trang )

The University of Information Technology – VNU
BÁO CÁO THỰC HÀNH
MÔN HỌC : HỆ ĐIỀU HÀNH
Tp Hồ Chí Minh ,tháng 12 năm 2009
Tác giả : Trần Thế Toàn .
1. Nội dung bài tập thực hành :
Bài a6 : Viết chương trình giao tiếp giữa hai tiến trình bằng cách sử dụng
shared memory .Tiến trình A gửi 1 thông điệp(message ) sang tiến trình B
và đợi tiến trình B phản hồi .Tiến trình B đợi thông điệp từ tiến trình A , sau
đó phản hồi thông điệp cho tiến trình A .
2. Hướng giải quyết cho bài tập :
Ta dùng cơ chế shared-memory thông qua memory mapped files .
Hai tiến trình tham gia vàp quá trình giao tiếp là Proccess P0 và Process P1.
Trong đó , đầu tiên P0 sẽ tạo ra File-mapping object , và chia sẻ file-
mapping object này cho P1 thông qua tên của File-mapping object .P0 liên
kết với File-mapping Object này trên cơ sở tạo ra một view trên vùng nhớ
được liên kết tới , nhờ P0 tạo 1 view riêng cho mình rồi map tới file được
chia sẻ .
P1 không tạo File-mapping Object nữa , nó sử dụng File-mapping object do
P0 tạo ra , P1 mở file mapping object và tạo 1 view riêng của nó , map vùng
nhớ của tiến trình tới vùng dữ liệu chia sẻ giữa P0 và P1 .
Sau khi việc chia sẻ vùng nhớ chung đã hoàn thành , ta tiến hành việc thực
hiện giao tiếp giữa hai tiến trình ( hay có thể gọi là “chat” ).Tiến trình P0
sau khi tạo ra vùng dữ liệu chia sẻ , P1 sẽ mở 1 view lên vùng dữ liệu chia
sẻ này , và sẽ là tiến trình giao tiếp trước . Sau khi P1 gửi thông điệp tới P0 ,
P1 sẽ không còn khả năng gửi tiếp thông điệp nữa mà nó phải chờ P0 hồi
đáp lại 1 thông điệp .
Việc giao tiếp giữa 2 tiến trình sẽ kết thúc nếu có bất kì bên nào nhập vào từ
khóa “exit” , sau đó ấn Enter .
3. Cài đặt bài toán trên ngôn ngữ lập trình C :
a. Tiến trình P0 :


Bước 1 : Tạo File-mapping Object .
This document is a part of Open Source Project from a UIT’s Student – 08520604 .
You can you this for any purpose as you want , but make sure it’s is legal in laws .
Contact : Page 1
The University of Information Technology – VNU
hMapFile có kiểu HANDLE là giá trị trả về của hàm
CreateFileMapping(…).
HANDLE WINAPI CreateFileMapping(
__in HANDLE hFile,
__in LPSECURITY_ATTRIBUTES lpAttributes,
__in DWORD Protect,
__in DWORD dwMaximumSizeHigh,
__in DWORD dwMaximumSizeLow,
__in LPCTSTR lpName
);
Trong đó , tham số thứ nhất là HANLDE hFile , do yêu cầu của chương trình
không yêu cầu lưu lại chat-log , để đơn giản cho chương trình , ta đưa vào giá trị
INVALID_HANDLE_VALUE , nghĩa là thay vì tạo ra một file-mapping Object
lên 1 file trên Disk , ta sẽ tạo một file-mapping Object lên Paging-File trong bộ
nhớ .
Với dòng lệnh trên ta tạo ra một File Mapping Object được xác định bởi
MapObjName , được chia sẻ với thuộc tính PAGE_READWRITE.
Bước 2 :
Sau đó , ta tạo 1 view của P0 tới file – mapping .
LPVOID WINAPI MapViewOfFile(
__in HANDLE hFileMappingObject,
__in DWORD dwDesiredAccess,
__in DWORD dwFileO!setHigh,
__in DWORD dwFileO!setLow,
__in SIZE_T dwNumberOfBytesToMap

);
This document is a part of Open Source Project from a UIT’s Student – 08520604 .
You can you this for any purpose as you want , but make sure it’s is legal in laws .
Contact : Page 2
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL , PAGE_READWRITE ,
0 , BUF_SIZE , MapObjName );
pBuf = (LPCTSTR)MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS , 0 ,
0 , BUF_SIZE);
The University of Information Technology – VNU
Kết quả là hàm sẽ trả về 1 con trỏ tới tới đầu block bộ nhớ của mapping view .
Con trỏ pBuf sau này sẽ được ta dùng để ghi và đọc thông điệp từ vùng nhớ chia
sẻ .
Bước 3 :
Chương trình bước vào vòng lặp vô cùng while(1) với hai thao tác đọc thông tin từ
vùng nhớ chia sẻ , in lên màn hình và ghi thông tin lên vùng nhớ chia sẻ .
Việc đọc thông tin và ghi thông tin của tiến trình P0 và P1 được điều khiển bởi
vùng nhớ chia sẻ thứ hai trong chương trình mà đại diện cho giá trị của vùng nhớ
là biến turn . Trong vòng lặp while(1) bên trong vòng lặp while(1) lớn , ta liên tục
thực hiện việc kiểm tra xem đã tới lượt P0 thực hiện đọc thông trong vùng nhớ chia
sẻ ra và in thông tin đó lên màn hình hay chưa :

Chỉ khi thỏa điều kiện biến turn mang giá trị 0 thì P0 mới thực hiện việc đọc
thông tin của mình . Với giá trị biến turn bằng 0 nghĩa là P1 đã thực hiện xong
việc ghi thông điệp vào vùng nhớ chia sẻ .
Bước 5 :
Sau khi thực hiện xong việc đọc thông tin từ vùng nhớ chia sẻ và in lên màn hình ,
tới lượt P0 được truyền đi thông điệp của nó .Chương trình thực thi câu lệnh
fgets() có tác dụng lấy nội dung phím gõ vào từ vùng đệm bàn phím và lưu vào
This document is a part of Open Source Project from a UIT’s Student – 08520604 .
You can you this for any purpose as you want , but make sure it’s is legal in laws .

Contact : Page 3
while(1)
{
CopyMemory((void *)BufferOut , (PVOID)pFlag , 10);
turn = atoi(BufferOut);
if(turn == 0)
{
CopyMemory((void*)inb ,(PVOID)pBuf , BUF_SIZE );
if(inb != "")
printf(inb);
break;
}
}

The University of Information Technology – VNU
trong đệm outb .Nếu chuỗi nhập vào là “exit\n” thì chương trình sẽ thoát khỏi quá
trình giao tiếp .Ta thực hiện việc ghi thông tin lấy từ vùng đệm bàn phím lên
vùng nhớ chia sẻ .
Để đảm bảo thông điệp sau khi được P0 cập nhập thì ta phải được P1 “ phát hiện”
ra và in lên màn hình , ta sử dụng một cơ chế đồng bộ riêng sẽ được mô tả chi tiết
ở phần tiếp theo của báo cáo này .
Ta thực hiện việc cập nhật vùng nhớ điều khiển sau khi đã tiến hành ghi thông tin
lên vùng nhớ chia sẻ .
Vòng lặp của chương trình cứ tiếp tục thực hiện .
Các thao tác kết thúc chương trình bao gồm UnmapViewOfFile và CloseHandle để
tránh memory-leakage .
b. Tiến trình P1 :
Về cơ bản thì các cài đặt trong P1 tương tự như P0 , ta sẽ lượt sơ qua các
thao tác chính để thấy sự giống nhau này :
Trong vòng lặp while(1) , chương trình sẽ lần lượt thực hiện qua các thao

tác sau đây .
Bước 1 : OpenFileMapping() trên file-mapping Object do P0 tạo ra trước .
This document is a part of Open Source Project from a UIT’s Student – 08520604 .
You can you this for any purpose as you want , but make sure it’s is legal in laws .
Contact : Page 4
fgets(outb , BUF_SIZE , stdin);
if(strcmp(outb , QUIT) == 0) //chuoi nhap vao la "exit\n"
{
printf("\nChuong trinh dang thoat !\n");
strcpy(outb , "");
exit(1);
}
CopyMemory((PVOID)pBuf , (void *)outb , BUF_SIZE);
itoa(1 , BufferIn , 10);
CopyMemory((PVOID)pFlag , (void *)BufferIn , 10);
The University of Information Technology – VNU
Bước 2 : Tạo một view lên vùng nhớ chia sẻ , giá trị trả về là 1 con trỏ , trỏ
tới địa chỉ đầu tiên trong vùng nhớ chia sẻ . Với thao tác này ta đã map vùng
nhớ của P1 tới vùng nhớ chia sẻ chung giữa P0 và P1.
Bước 3 : Tương tự như P0 , ta cũng lần lượt thực hiện hai thao tác , đó là
đọc thông tin trong vùng nhớ chia sẻ lên màn hình và ghi thông tin lên vùng nhớ
chia sẻ thông qua bộ đệm bàn phím .
Cuối cùng là các thao tác kết thúc chương trình để tránh Memory-leakage .
c. Cơ chế đồng bộ hóa giữa hai tiến trình P0 va P1 :
• Vấn đề đặt ra :
Khi P1 bắt đầu phiên giao tiếp với P0 , sau khi P1 gửi một thông điệp
sang P0 thì P0 ” nhận thấy được ” ( detect ) và biết được tới lượt nó đọc
thông điệp lên màn hình và gửi ngược lại 1 thông điệp khác P1 để duy trì
giao tiếp .Mặt khác, sau khi 1 tiến trình đã gửi thông điệp đi rồi , nó
không có quyền tiếp tục gửi thông điệp đi nữa .

• Giải quyết vấn đề :
Ta sử dụng 1 biến turn là thể hiện của vùng nhớ chia sẻ thực hiện việc
đồng bộ giữa hai tiến trình .
Vùng nhớ chia sẻ này dùng cơ chế Memory-mapped file , thông qua điều
khiển hFlag :

Với vùng nhớ chia sẻ được tạo ra này , ta thực hiện cập nhật 2 giá trị 0 và 1
tùy theo P1 hay P0 .Với giá trị tương ứng của vùng nhớ mà đại diện là biến turn ,
ta có thể quyết định việc đọc thông điệp và ghi thông điệp lên màn hình , cũng như
gửi thông điệp giao tiếp là thuộc về tiến trình nào ? P0 hay P1 .
Trước tiên , P0 tạo ra vùng nhớ chia sẻ này , nhưng ta muốn rằng P1 phải là
tiến trình đầu tiên thực hiện việc gửi thông điệp cho P0 , ta gán giá trị cho vùng
nhớ ban đầu là 1 .
This document is a part of Open Source Project from a UIT’s Student – 08520604 .
You can you this for any purpose as you want , but make sure it’s is legal in laws .
Contact : Page 5
pBuf =(LPCTSTR) MapViewOfFile(hMapFile , FILE_MAP_ALL_ACCESS,
0,0, BUF_SIZE);
hFlag = CreateFileMapping(INVALID_HANDLE_VALUE , NULL ,
PAGE_READWRITE , 0 , BUF_SIZE , Flag);
The University of Information Technology – VNU
Như vậy khi P0 bắt đầu vòng lặp kiểm tra việc đọc thông tin trong vùng nhớ
chia sẻ và ghi lên màn hình , nó sẽ bị kẹt trong vòng lặp đó .
Chỉ đến khi nào turn có giá trị là 0 , và việc in thông điệp ra màn hình được thực
thi thì P0 mới thoát khỏi vòng lặp này .(Tại đây nảy sinh vấn đề lãng phí tài
nguyên mà ta sẽ nói tới sau .)
Sau khi P0 thực hiện việc ghi thông điệp vào vùng nhớ chia sẻ , nó sẽ thay đổi giá
trị trong vùng nhớ điều khiển , như vậy P1 trong khi chạy liên tục vòng lặp kiểm
tra biến turn để kiểm tra tới lượt P1 chưa sẽ “phát hiện” ra sự thay đổi giá trị biến
turn trong P1 , nó sẽ tiến hành đọc thông điệp lên màn hình , sau đó lại ghi thông

điệp lên vùng nhớ chia sẻ , rồi lại thay đổi giá trị trong vùng nhớ điều khiển .Cứ
như vậy quá trình giao tiếp diễn ra .
4. Các vấn đề còn tồn tại của giải pháp đã đưa ra :
Cơ chế “lắng nghe” giữa hai tiến trình được cài đặt bằng vòng lặp while ().
This document is a part of Open Source Project from a UIT’s Student – 08520604 .
You can you this for any purpose as you want , but make sure it’s is legal in laws .
Contact : Page 6
//Khoi gan luot doc thong tin dau tien la cua Process 1.
itoa(1 , BufferIn , 10);
CopyMemory((PVOID)pFlag , (void*)BufferIn , 10);
while(1)
{
CopyMemory((void *)BufferOut , (PVOID)pFlag , 10);
turn = atoi(BufferOut);
if(turn == 0)
{
CopyMemory((void*)inb ,(PVOID)pBuf , BUF_SIZE );
if(inb != "")
printf(inb);
break;
}
}
//Thay doi gia tri trong vung nho dieu khien.
itoa(1 , BufferIn , 10);
CopyMemory((PVOID)pFlag , (void *)BufferIn , 10);
The University of Information Technology – VNU
Do vậy , cả hai tiến trình liên tục kiểm tra xem nó đã có quyền đọc thông
tin lên màn hình hay chưa , chính cơ chế Busy-waiting này thực sự làm tiêu
tốn tài nguyên của máy tính trong khi chạy cả 2 tiến trình .
Giải pháp : Dùng cơ chế Sleep-and-wakeup , thông qua việc dùng

semaphore .
5. Tài liệu tham khảo :
- Operating System Concepts 6
th
edition by Silberchart Galvin Gagne
ISBN : 9812-53-055X
- Windows System Progamming 3
rd
edition by Johnson M.Hart
ISBN : 0-321-25619-0
- Microsoft Development Network ( MSDN Library ).
This document is a part of Open Source Project from a UIT’s Student – 08520604 .
You can you this for any purpose as you want , but make sure it’s is legal in laws .
Contact : Page 7

×