PHÁT BIểU BÀI TOÁN SX-TT
Trang 1 trong tổng số 1 trang
PHÁT BIểU BÀI TOÁN SX-TT
Giả sử có bộ nhớ đệm bao gồm nhiều khoang (items) được tiến trình Producer luôn luôn đưa các sản phẩm P, p,s vào.
Tiến trình comsumer luôn luôn lấy sản phẩm ra theo đúng thứ tự.
Công việc của Producer phải đồng bộ với comsumer: ko được đưa sản phẩm vào khi buffer đầy, ko được lấy sản phẩm ra khi chưa có.
Sản xuất-Tiêu thụ
(đồng bộ bằng 2 đèn hiệu)
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
char s[BUFFER_SIZE];
int in=0;
int out=0;
int nextProduced=1;
HANDLE semEmpty, semFull; // Hai đèn hiệu
//semEmpty: đèn hiệu kiểm soát số vùng trống trong bộ đệm
//semFull: đèn hiệu kiểm soát số sản phẩm trong bộ đệm
CRITICAL_SECTION critSec; Biến kiểu Mutex ; đèn hiệu nhị phân nội tiến trình
void Producer(void * p){
while (1){
// ... Sản xuất (nextProduced)
// Chờ đến khi có chỗ trống
WaitForSingleObject(semEmpty, INFINITE);
EnterCriticalSection(&critSec);
buffer[in]=nextProduced++;
switch ((int)p){
case 1:
s[in]=’P’;
break;
case 2:
s[in]=’p’;
break;
default:
s[in]=’S’;
};
in=(in+1)%BUFFER_SIZE;
// Tăng (semFull) lên 1
ReleaseSemaphore(semFull, 1, NULL);
LeaveCriticalSection(&critSec);
SuspendThread(GetCurrentThread());
}
}
void Consumer(){
int nextConsumed;
while (1){
// Chờ đến khi có sản phẩm
WaitForSingleObject(semFull, INFINITE);
EnterCriticalSection(&critSec);
nextConsumed=buffer[out];
out=(out+1)%BUFFER_SIZE;
// Tăng (semEmpty) lên 1
ReleaseSemaphore (semEmpty, 1, NULL);
LeaveCriticalSection(&critSec);
// ... Tiêu thụ (nextConsumed)
SuspendThread(GetCurrentThread());
}
}
void ShowBuffer(){ // In nội dung bộ đệm
const char * LeftMargin="\n ";
int i;
printf(LeftMargin);
for(i=0; i<(in*5); i++) putchar(' '); printf("!in");
printf(LeftMargin);
for (i=0; i<BUFFER_SIZE-1; i++)
printf("%c%2d, ", s[i], buffer[i]);
printf("%c%2d", s[BUFFER_SIZE-1], buffer[BUFFER_SIZE-1]);
printf(LeftMargin);
for(i=0; i<(out*5); i++) putchar(' ');
printf("^out");
printf("\n");
}
int main(){
HANDLE ProducerHandle1, ProducerHandle2;
HANDLE ConsumerHandle1, ConsumerHandle2;
DWORD ProducerID1, ProducerID2;
DWORD ConsumerID1, ConsumerID2;
semEmpty=CreateSemaphore(0, BUFFER_SIZE, BUFFER_SIZE, 0);
semFull=CreateSemaphore(0, 0, BUFFER_SIZE, 0);
InitializeCriticalSection(&critSec);
// Tạo các luồng nhưng ở trạng thái ngủ (Suspend)
ProducerHandle1=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer, (void *) 1, 4, &ProducerID1);
ProducerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer, (void *) 2, 4, &ProducerID2);
ConsumerHandle1=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer, 0, 4, &ConsumerID1);
ConsumerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer, 0, 4, &ConsumerID2);
while(1)
{
printf("\n- Nhấn P/p để sản xuất, C/c để tiêu thụ:");
switch (getch()){
case 'P': // Đánh thức luồng SX 1
ResumeThread(ProducerHandle1);
break;
case 'p': // Đánh thức luồng SX 2
ResumeThread(ProducerHandle2);
break;
case 'C': // Đánh thức luồng TT 1
ResumeThread(ConsumerHandle1);
break;
case 'c': // Đánh thức luồng TT 2
ResumeThread(ConsumerHandle2);
break;
case '0': // Kết thúc ứng dụng
printf("\n");
CloseHandle(semEmpty);
CloseHandle(semFull);
DeleteCriticalSection(&critSec);
return 0;
}
EnterCriticalSection(&critSec);
ShowBuffer();
LeaveCriticalSection(&critSec);
}
}
ghi chú
(theo dinh nhĩa)typedef int semaphore;
semaphore s = n;
(thực thi trong C)HANDLE s;
s=CreateSemaphore (0, n, max, t);
// t -tên đèn hiệu hoặc 0
// nếu t là 1 chuỗi ký tự trong ngoặc kép(" ") thì đó là tên ấn định cho đèn hiệu liên tiến trình(liên lạc được tiến trình khác ) . Nếu dùng 0 thay cho t; null thi đèn hiệu mới tạo chỉ có nội tiến trình (hiệu quả hơn nhanh hơn)
(thực thi trong C)wait (s);
(thực thi trong C)WaitForSingleObject (s, timeout); /* timeout = INFINITE hoặc số mili giây chờ*/
(thực thi trong C)signal (s);
(thực thi trong C)ReleaseSemaphore (s, 1, NULL);
Tiến trình comsumer luôn luôn lấy sản phẩm ra theo đúng thứ tự.
Công việc của Producer phải đồng bộ với comsumer: ko được đưa sản phẩm vào khi buffer đầy, ko được lấy sản phẩm ra khi chưa có.
Sản xuất-Tiêu thụ
(đồng bộ bằng 2 đèn hiệu)
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
char s[BUFFER_SIZE];
int in=0;
int out=0;
int nextProduced=1;
HANDLE semEmpty, semFull; // Hai đèn hiệu
//semEmpty: đèn hiệu kiểm soát số vùng trống trong bộ đệm
//semFull: đèn hiệu kiểm soát số sản phẩm trong bộ đệm
CRITICAL_SECTION critSec; Biến kiểu Mutex ; đèn hiệu nhị phân nội tiến trình
void Producer(void * p){
while (1){
// ... Sản xuất (nextProduced)
// Chờ đến khi có chỗ trống
WaitForSingleObject(semEmpty, INFINITE);
EnterCriticalSection(&critSec);
buffer[in]=nextProduced++;
switch ((int)p){
case 1:
s[in]=’P’;
break;
case 2:
s[in]=’p’;
break;
default:
s[in]=’S’;
};
in=(in+1)%BUFFER_SIZE;
// Tăng (semFull) lên 1
ReleaseSemaphore(semFull, 1, NULL);
LeaveCriticalSection(&critSec);
SuspendThread(GetCurrentThread());
}
}
void Consumer(){
int nextConsumed;
while (1){
// Chờ đến khi có sản phẩm
WaitForSingleObject(semFull, INFINITE);
EnterCriticalSection(&critSec);
nextConsumed=buffer[out];
out=(out+1)%BUFFER_SIZE;
// Tăng (semEmpty) lên 1
ReleaseSemaphore (semEmpty, 1, NULL);
LeaveCriticalSection(&critSec);
// ... Tiêu thụ (nextConsumed)
SuspendThread(GetCurrentThread());
}
}
void ShowBuffer(){ // In nội dung bộ đệm
const char * LeftMargin="\n ";
int i;
printf(LeftMargin);
for(i=0; i<(in*5); i++) putchar(' '); printf("!in");
printf(LeftMargin);
for (i=0; i<BUFFER_SIZE-1; i++)
printf("%c%2d, ", s[i], buffer[i]);
printf("%c%2d", s[BUFFER_SIZE-1], buffer[BUFFER_SIZE-1]);
printf(LeftMargin);
for(i=0; i<(out*5); i++) putchar(' ');
printf("^out");
printf("\n");
}
int main(){
HANDLE ProducerHandle1, ProducerHandle2;
HANDLE ConsumerHandle1, ConsumerHandle2;
DWORD ProducerID1, ProducerID2;
DWORD ConsumerID1, ConsumerID2;
semEmpty=CreateSemaphore(0, BUFFER_SIZE, BUFFER_SIZE, 0);
semFull=CreateSemaphore(0, 0, BUFFER_SIZE, 0);
InitializeCriticalSection(&critSec);
// Tạo các luồng nhưng ở trạng thái ngủ (Suspend)
ProducerHandle1=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer, (void *) 1, 4, &ProducerID1);
ProducerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer, (void *) 2, 4, &ProducerID2);
ConsumerHandle1=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer, 0, 4, &ConsumerID1);
ConsumerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer, 0, 4, &ConsumerID2);
while(1)
{
printf("\n- Nhấn P/p để sản xuất, C/c để tiêu thụ:");
switch (getch()){
case 'P': // Đánh thức luồng SX 1
ResumeThread(ProducerHandle1);
break;
case 'p': // Đánh thức luồng SX 2
ResumeThread(ProducerHandle2);
break;
case 'C': // Đánh thức luồng TT 1
ResumeThread(ConsumerHandle1);
break;
case 'c': // Đánh thức luồng TT 2
ResumeThread(ConsumerHandle2);
break;
case '0': // Kết thúc ứng dụng
printf("\n");
CloseHandle(semEmpty);
CloseHandle(semFull);
DeleteCriticalSection(&critSec);
return 0;
}
EnterCriticalSection(&critSec);
ShowBuffer();
LeaveCriticalSection(&critSec);
}
}
ghi chú
(theo dinh nhĩa)typedef int semaphore;
semaphore s = n;
(thực thi trong C)HANDLE s;
s=CreateSemaphore (0, n, max, t);
// t -tên đèn hiệu hoặc 0
// nếu t là 1 chuỗi ký tự trong ngoặc kép(" ") thì đó là tên ấn định cho đèn hiệu liên tiến trình(liên lạc được tiến trình khác ) . Nếu dùng 0 thay cho t; null thi đèn hiệu mới tạo chỉ có nội tiến trình (hiệu quả hơn nhanh hơn)
(thực thi trong C)wait (s);
(thực thi trong C)WaitForSingleObject (s, timeout); /* timeout = INFINITE hoặc số mili giây chờ*/
(thực thi trong C)signal (s);
(thực thi trong C)ReleaseSemaphore (s, 1, NULL);
HaVietAnh(I92C)- Tổng số bài gửi : 62
Join date : 14/09/2010
Similar topics
» Thảo luận Bài 4
» Phát biểu bài toán sản xuất và tiêu thụ
» Phát biểu bài toán sản xuất tiêu thụ
» Thảo luận Bài 7
» Thảo luận Bài 4
» Phát biểu bài toán sản xuất và tiêu thụ
» Phát biểu bài toán sản xuất tiêu thụ
» Thảo luận Bài 7
» Thảo luận Bài 4
Trang 1 trong tổng số 1 trang
Permissions in this forum:
Bạn không có quyền trả lời bài viết