PHÁT BIểU BÀI TOÁN SX-TT

Go down

PHÁT BIểU BÀI TOÁN SX-TT

Bài gửi  HaVietAnh(I92C) on 23/11/2010, 21:59

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);

HaVietAnh(I92C)

Tổng số bài gửi : 62
Join date : 14/09/2010

Xem lý lịch thành viên

Về Đầu Trang Go down

Về Đầu Trang


 
Permissions in this forum:
Bạn không có quyền trả lời bài viết