THỰC THI VẤN ĐỀ “SẢN XUẤT – TIÊU THỤ(BUSY_WAITING)
3 posters
Trang 1 trong tổng số 1 trang
THỰC THI VẤN ĐỀ “SẢN XUẤT – TIÊU THỤ(BUSY_WAITING)
THỰC THI VẤN ĐỀ “SẢN XUẤT – TIÊU THỤ”
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int in=0;
int out=0;
int nextProduced=1;
void Producer(){
while (1//Điều kiện đúng){
// ... Sản xuất (nextProduced)
while(((in+1)%BUFFER_SIZE)==out);Nếu điều kiện đúng chờ bận,lặp vô tận
//Còn nếu sai thì thực hiện 3 lệnh dưới
//VD: Khi đến ngã 4 gặp đèn đỏ, mọi người liên tục nhìn xem thử đèn đã xanh chưa, nếu vẫn còn đỏ thì vẫn chờ, đến lúc nào đèn xanh mới được đi.
buffer[in]=nextProduced++;
in=(in+1)%BUFFER_SIZE;
SuspendThread(GetCurrentThread());//Tạm ngưng luồng hiện hành
(Nhưng mục đích để làm gì thì mình không biết_ Bạn nào hiểu rõ thì giải thích cho mình biết với)
}
}
void Consumer(){
int nextConsumed;
while (1){
while(in==out);// Chờ bận
VD: Khi xếp gạo vào kho, nếu chưa có chỗ trống thì người khuôn vác vẫn cứ vác bao gạo trên vai vậy, đến lúc nào có chỗ trống thì đặt vào.
nextConsumed=buffer[out];
out=(out+1)%BUFFER_SIZE;
// ... Tiêu thụ (nextConsumed)
Sleep(GetTickCount()%5000);
//GetTickCount(): là lấy số ms kể từ khi hệ thống khởi động đến giờ hiện tại
(Còn chia cho 5000 thì mình không nhớ Thầy giải thích thế nào?)
}
}
void ShowBuffer(){ // In nội dung Buffer
const char * LeftMargin="\\n\\t";
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("S%2d, ",buffer[i]);
printf("S%2d",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;
// Tạo 2 luồng Sản xuất trong trạng thái ngủ
ProducerHandle1=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer,
0, 4, &ProducerID1);
ProducerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer,
0, 4, &ProducerID2);
// Tạo 2 luồng Tiêu thụ thi hành ngay
ConsumerHandle1=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer,
0, 0, &ConsumerID1);
ConsumerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer,
0, 0, &ConsumerID2);
while(1){
printf("\\n- Nhấn P/p để sản xuất, 0 để kết thúc:”);
switch (getch()){
case 'P':
ResumeThread(ProducerHandle1);
break;
case 'p':
ResumeThread(ProducerHandle2);
break;
case '0':
CloseHandle(ProducerHandle1);
CloseHandle(ProducerHandle2);
CloseHandle(ConsumerHandle1);
CloseHandle(ConsumerHandle2);
return 0;
}
Sleep(1);// ngủ 1ms, để cho các tiến trình hoàn thành xong
// hết các công việc rồi mới ShowBuffer();
VD: nếu không ngủ 1ms thì thực trạng sẽ như ví dụ sau:
Khi mình lên bảng viết: Tôi tên là Nguyễn Thị Phương Chi
Nhưng mới viết đến Nguyễn Thị Phương thì có người chụp hình lại
Đến lúc người đó đem xem thì lúc đó mình không phải tên Nguyễn Thị Phương Chi mà là Nguyễn Thị Phương
ShowBuffer();
}
}
Mình post lên để mọi người cùng tham khảo, nếu có thiếu sót thì mấy bạn bổ sung.
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int in=0;
int out=0;
int nextProduced=1;
void Producer(){
while (1//Điều kiện đúng){
// ... Sản xuất (nextProduced)
while(((in+1)%BUFFER_SIZE)==out);Nếu điều kiện đúng chờ bận,lặp vô tận
//Còn nếu sai thì thực hiện 3 lệnh dưới
//VD: Khi đến ngã 4 gặp đèn đỏ, mọi người liên tục nhìn xem thử đèn đã xanh chưa, nếu vẫn còn đỏ thì vẫn chờ, đến lúc nào đèn xanh mới được đi.
buffer[in]=nextProduced++;
in=(in+1)%BUFFER_SIZE;
SuspendThread(GetCurrentThread());//Tạm ngưng luồng hiện hành
(Nhưng mục đích để làm gì thì mình không biết_ Bạn nào hiểu rõ thì giải thích cho mình biết với)
}
}
void Consumer(){
int nextConsumed;
while (1){
while(in==out);// Chờ bận
VD: Khi xếp gạo vào kho, nếu chưa có chỗ trống thì người khuôn vác vẫn cứ vác bao gạo trên vai vậy, đến lúc nào có chỗ trống thì đặt vào.
nextConsumed=buffer[out];
out=(out+1)%BUFFER_SIZE;
// ... Tiêu thụ (nextConsumed)
Sleep(GetTickCount()%5000);
//GetTickCount(): là lấy số ms kể từ khi hệ thống khởi động đến giờ hiện tại
(Còn chia cho 5000 thì mình không nhớ Thầy giải thích thế nào?)
}
}
void ShowBuffer(){ // In nội dung Buffer
const char * LeftMargin="\\n\\t";
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("S%2d, ",buffer[i]);
printf("S%2d",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;
// Tạo 2 luồng Sản xuất trong trạng thái ngủ
ProducerHandle1=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer,
0, 4, &ProducerID1);
ProducerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer,
0, 4, &ProducerID2);
// Tạo 2 luồng Tiêu thụ thi hành ngay
ConsumerHandle1=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer,
0, 0, &ConsumerID1);
ConsumerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer,
0, 0, &ConsumerID2);
while(1){
printf("\\n- Nhấn P/p để sản xuất, 0 để kết thúc:”);
switch (getch()){
case 'P':
ResumeThread(ProducerHandle1);
break;
case 'p':
ResumeThread(ProducerHandle2);
break;
case '0':
CloseHandle(ProducerHandle1);
CloseHandle(ProducerHandle2);
CloseHandle(ConsumerHandle1);
CloseHandle(ConsumerHandle2);
return 0;
}
Sleep(1);// ngủ 1ms, để cho các tiến trình hoàn thành xong
// hết các công việc rồi mới ShowBuffer();
VD: nếu không ngủ 1ms thì thực trạng sẽ như ví dụ sau:
Khi mình lên bảng viết: Tôi tên là Nguyễn Thị Phương Chi
Nhưng mới viết đến Nguyễn Thị Phương thì có người chụp hình lại
Đến lúc người đó đem xem thì lúc đó mình không phải tên Nguyễn Thị Phương Chi mà là Nguyễn Thị Phương
ShowBuffer();
}
}
Mình post lên để mọi người cùng tham khảo, nếu có thiếu sót thì mấy bạn bổ sung.
nguyenthiphuongchi- Tổng số bài gửi : 57
Join date : 24/02/2009
Re: THỰC THI VẤN ĐỀ “SẢN XUẤT – TIÊU THỤ(BUSY_WAITING)
Hi PhuongChi,
Mình sẽ giải thích một vài chổ bạn chưa rõ.
1. SuspendThread(GetCurrentThread());
Lệnh này nó sẽ thực hiện như sau: Đầu tiên hàm GetCurrentThread() trả về mục quản của luồng hiện hành (Vd:#500 chẳng hạn) và hàm SuspendThread sẽ tạm dừng luồng #500 và luồng #500 sẽ được đánh thức trở lại bằng hàm ResumeThread trong hàm main.
2. Sleep(GetTickCount()%5000);
Lệnh này có ý ghĩa là: Ngủ với thời gian không quá 5 giây (vd: tối đa là 4.9s).
Hy vọng bạn đã rõ.
Thanks!
Tuấn
Mình sẽ giải thích một vài chổ bạn chưa rõ.
1. SuspendThread(GetCurrentThread());
Lệnh này nó sẽ thực hiện như sau: Đầu tiên hàm GetCurrentThread() trả về mục quản của luồng hiện hành (Vd:#500 chẳng hạn) và hàm SuspendThread sẽ tạm dừng luồng #500 và luồng #500 sẽ được đánh thức trở lại bằng hàm ResumeThread trong hàm main.
2. Sleep(GetTickCount()%5000);
Lệnh này có ý ghĩa là: Ngủ với thời gian không quá 5 giây (vd: tối đa là 4.9s).
Hy vọng bạn đã rõ.
Thanks!
Tuấn
ngoanhtuan- Tổng số bài gửi : 14
Join date : 08/05/2009
THỰC THI VẤN ĐỀ “SẢN XUẤT – TIÊU THỤ(BUSY_WAITING)
cái hàm Sleep(GetTickCount()%5000); mình vẫn còn mơ hồ lắm. Bạn có thể nói rõ hơn 1 tí được k?
Và tại sao phải tạm ngưng luồng hiện hành đó. Có phải như ban lyhuyvinh đã viết ở bài toán SX_TT là ngưng sản xuất khi hàng đợi đầy, còn ngưng tiêu thụ khi hàng đợi rỗng k?
Và tại sao phải tạm ngưng luồng hiện hành đó. Có phải như ban lyhuyvinh đã viết ở bài toán SX_TT là ngưng sản xuất khi hàng đợi đầy, còn ngưng tiêu thụ khi hàng đợi rỗng k?
nguyenthiphuongchi- Tổng số bài gửi : 57
Join date : 24/02/2009
Re: THỰC THI VẤN ĐỀ “SẢN XUẤT – TIÊU THỤ(BUSY_WAITING)
Hi phuongchi,
Để giải thích cho hàm này Sleep(GetTickCount()%5000) bạn cần phải hiểu:
- GetTickCount() sẽ trả về một con số (vd: 5001)->Cái này bạn đã biết.
- "%": Phép chia lấy phần dư. (vd: 0%5000 = 0, 1%5000 = 1, ..., 4999%5000=4999, 5000%5000=0). Về nguyên tắc phép chia lấy dư như mình đưa ví dụ, kết quả sẽ ra 1 con số, mà con số đó không bao giờ vượt qúa 5000 (tối đa là 4999).
Thanks!
Tuấn
Để giải thích cho hàm này Sleep(GetTickCount()%5000) bạn cần phải hiểu:
- GetTickCount() sẽ trả về một con số (vd: 5001)->Cái này bạn đã biết.
- "%": Phép chia lấy phần dư. (vd: 0%5000 = 0, 1%5000 = 1, ..., 4999%5000=4999, 5000%5000=0). Về nguyên tắc phép chia lấy dư như mình đưa ví dụ, kết quả sẽ ra 1 con số, mà con số đó không bao giờ vượt qúa 5000 (tối đa là 4999).
Thanks!
Tuấn
ngoanhtuan- Tổng số bài gửi : 14
Join date : 08/05/2009
THỰC THI VẤN ĐỀ “SẢN XUẤT – TIÊU THỤ(BUSY_WAITING)
Cám ơn ban ngoanhtuan nhiều. bây giờ thì mình đã hiểu câu lệnh đó.
Mình thấy bạn hiểu code lắm đó. Bạn có thể post những bài còn lại cho mọi người cùng tham khảo đi.
Mình thấy bạn hiểu code lắm đó. Bạn có thể post những bài còn lại cho mọi người cùng tham khảo đi.
nguyenthiphuongchi- Tổng số bài gửi : 57
Join date : 24/02/2009
Re: THỰC THI VẤN ĐỀ “SẢN XUẤT – TIÊU THỤ(BUSY_WAITING)
Cám ơn bạn ngoanhtuan đã giải thích bổ sung đầy đủ hơn cho tụi mình tham khảo
phuongdtk- Tổng số bài gửi : 56
Join date : 19/02/2009
Similar topics
» Thi Kiểm tra Giữa kỳ
» bổ sung them vd busywaiting
» Các bạn ơi danh sách tên sinh viên thực tập?
» Lịch thực hành
» Đề thi thực hành khóa trước
» bổ sung them vd busywaiting
» Các bạn ơi danh sách tên sinh viên thực tập?
» Lịch thực hành
» Đề thi thực hành khóa trước
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