Tin học
Bạn có muốn phản ứng với tin nhắn này? Vui lòng đăng ký diễn đàn trong một vài cú nhấp chuột hoặc đăng nhập để tiếp tục.

Giải thích code cho vấn đề sản xuất tiêu thụ

+7
BuiQuocDung14 (102c)
LuongThiXuanYen (102C)
NguyenVietHung (102C)
maivietthanh (i92c)
LuuDucPhu (102C)
nguyen huynh nhu (102C)
NguyenQuocHien(102C)
11 posters

Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  NguyenQuocHien(102C) 21/4/2011, 00:24

// Các bạn chịu khó đọc rồi xem có bổ sung gì không nha, đoạn chương trình này công nhận là rắc rối thiệt

#include <stdio.h>
#include <conio.h>
#include <windows.h> // lập trình đa luồng đồng hành, sử dụng được hàm win32 API

#define BUFFER_SIZE 10 // định nghĩa một buffer có số khoang chứa là 10

int buffer[BUFFER_SIZE];
int in=0; // biến in chứa giá trị chỉ vị trí xếp sản phẩm vào
int out=0;// biến out chứa giá trị chỉ vị trí lấy sản phẩm ra

int nextProduced=1;// biến trung gian, chứa số hiệu sản phẩm đầu tiên

void Producer(){ // hàm sản xuất
while (1){
// ... Sản xuất (nextProduced)
while(((in+1)%BUFFER_SIZE)==out);// khoang chứa đầy thì quẩn tại đây
buffer[in]=nextProduced++; // cho sản phẩm vào mảng tại vị trí in
in=(in+1)%BUFFER_SIZE; //sau khi chèn sản phẩm vào mảng, tăng in lên 1, nếu in đang nằm ở vị trí cuối mảng sẽ nhảy về đầu mảng
SuspendThread(GetCurrentThread()); //getcureentthred: hàm của thư viện win32 API, trả về giá trị mục quản của luồng hiện hành, vd: 1700. SuspendThread(): ngừng luồng có mục quản là giá trị trong ngoặc, vd: SuspendThread(1700) ngừng luồng có mục quản 1700
}
}

void Consumer(){
int nextConsumed; // biến chứa sản phẩm được tiêu thụ
while (1){
while(in==out); //trong khoang chứa hết sản phẩm thì quẩn tại đây
nextConsumed=buffer[out]; //sản phẩm ở vị trí buffer out được đưa vào biến netxconsumed
out=(out+1)%BUFFER_SIZE;//out tăng lên 1, nếu out đang nằm ở cuối mảng thì nhảy lên đầu mảng
// ... Tiêu thụ (nextConsumed)
Sleep(GetTickCount()%5000); // hàm gettickcount() sẽ trả về thời gian tính bằng ms trôi qua kể từ khi hệ thống khởi động tới thời điểm hiện tại, kết quả sẽ ra được con số rất lớn và chia lấy số dư cho 5000 sẽ ra được 1 con số từ 0-4999, cho luồng tiêu thụ này ngủ trong khoảng thời gian đó.
}
}

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; // lưu mục quản của 2 nhà sx vào 2 biến ProducerHandle1, ProducerHandle2
HANDLE ConsumerHandle1, ConsumerHandle2; //lưu mục quản của 2 nhà tiêu thụ

DWORD ProducerID1, ProducerID2; // mã số định danh của luồng sản xuất
DWORD ConsumerID1, ConsumerID2; // mã số định danh của luồng tiêu thụ

// 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);
//tạo 1 luồng sản xuất, luồng này sẽ lấy giá trị trả về của hàm Producer và được ép kiểu (LPTHREAD_START_ROUTINE), số 0 tiếp theo chỉ ra hàm Producer ko có tham biến, số 4 chỉ ra luồng vừa tạo sẽ không chạy mà ngủ luôn, &ProducerID1 chỉ ra luồng sẽ có mã số định danh là ProducerID1
// sau khi làm lệnh này, sẽ có 2 luồng, luồng ctrinh này và luồng producer
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);
//0: luồng tiêu thụ vận hành ngay, ko ngủ

ConsumerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer,
0, 0, &ConsumerID2);
while(1){
printf("\n- Nhap P/p de san xuat, 0 de ket thuc:”);
//P đánh thức nhà sx1, p sx2
switch (getch()){//biết người sử dụng bấm gì
case 'P':
ResumeThread(ProducerHandle1); //đánh thức luồng 1
break;
case 'p':
ResumeThread(ProducerHandle2);//đánh thức luồng 2
break;
case '0':
CloseHandle(ProducerHandle1);// hủy đối tượng(ở đây là luồng) có mục quản
CloseHandle(ProducerHandle2);
CloseHandle(ConsumerHandle1);
CloseHandle(ConsumerHandle2);
return 0;
}
Sleep(1);// ngủ 1 ms, tức là luồng chính sẽ trễ 1 chút để sx cho xong(chờ in tăng lên 1) rồi mới showbuffer ra
ShowBuffer();
}
}

NguyenQuocHien(102C)

Tổng số bài gửi : 33
Join date : 23/02/2011

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  nguyen huynh nhu (102C) 21/4/2011, 10:54

Thanks ban nha
nguyen huynh nhu (102C)
nguyen huynh nhu (102C)

Tổng số bài gửi : 19
Join date : 17/03/2011
Age : 35
Đến từ : BH-DN

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  LuuDucPhu (102C) 21/4/2011, 11:53

// 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);
//tạo 1 luồng sản xuất, luồng này sẽ lấy giá trị trả về của hàm Producer và được ép kiểu (LPTHREAD_START_ROUTINE), số 0 tiếp theo chỉ ra hàm Producer ko có tham biến, số 4 chỉ ra luồng vừa tạo sẽ không chạy mà ngủ luôn, &ProducerID1 chỉ ra luồng sẽ có mã số định danh là ProducerID1
// sau khi làm lệnh này, sẽ có 2 luồng, luồng ctrinh này và luồng producer
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);
//0: luồng tiêu thụ vận hành ngay, ko ngủ

Theo đoạn code thì tham số thứ 5 khi tạo một luồng mới nếu là 4 (trạng thái ngủ), 0 (trạng thái vận hành ngay khi được tạo ). Vậy có bạn nào rành về lập trình đa luồng có thể cho mình hỏi ngoài 2 giá trị 0 và 4 thì mình còn có thể truyền vào đó giá trị khác không ví dụ như 1, 2 hoặc 3... và những giá trị đó là những trạng thái nào của luồng ? Thks confused

LuuDucPhu (102C)

Tổng số bài gửi : 40
Join date : 17/02/2011

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  maivietthanh (i92c) 21/4/2011, 22:59

cám ơn bạn nhe,hôm trước mình chép không kịp.

maivietthanh (i92c)

Tổng số bài gửi : 27
Join date : 23/02/2011

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  NguyenVietHung (102C) 22/4/2011, 21:50

NguyenQuocHien(102C) đã viết:// Các bạn chịu khó đọc rồi xem có bổ sung gì không nha, đoạn chương trình này công nhận là rắc rối thiệt

#include <stdio.h>
#include <conio.h>
#include <windows.h> // lập trình đa luồng đồng hành, sử dụng được hàm win32 API

#define BUFFER_SIZE 10 // định nghĩa một buffer có số khoang chứa là 10

int buffer[BUFFER_SIZE];
int in=0; // biến in chứa giá trị chỉ vị trí xếp sản phẩm vào
int out=0;// biến out chứa giá trị chỉ vị trí lấy sản phẩm ra

int nextProduced=1;// biến trung gian, chứa số hiệu sản phẩm đầu tiên

void Producer(){ // hàm sản xuất
while (1){
// ... Sản xuất (nextProduced)
while(((in+1)%BUFFER_SIZE)==out);// khoang chứa đầy thì quẩn tại đây
buffer[in]=nextProduced++; // cho sản phẩm vào mảng tại vị trí in
in=(in+1)%BUFFER_SIZE; //sau khi chèn sản phẩm vào mảng, tăng in lên 1, nếu in đang nằm ở vị trí cuối mảng sẽ nhảy về đầu mảng
SuspendThread(GetCurrentThread()); //getcureentthred: hàm của thư viện win32 API, trả về giá trị mục quản của luồng hiện hành, vd: 1700. SuspendThread(): ngừng luồng có mục quản là giá trị trong ngoặc, vd: SuspendThread(1700) ngừng luồng có mục quản 1700
}
}

void Consumer(){
int nextConsumed; // biến chứa sản phẩm được tiêu thụ
while (1){
while(in==out); //trong khoang chứa hết sản phẩm thì quẩn tại đây
nextConsumed=buffer[out]; //sản phẩm ở vị trí buffer out được đưa vào biến netxconsumed
out=(out+1)%BUFFER_SIZE;//out tăng lên 1, nếu out đang nằm ở cuối mảng thì nhảy lên đầu mảng
// ... Tiêu thụ (nextConsumed)
Sleep(GetTickCount()%5000); // hàm gettickcount() sẽ trả về thời gian tính bằng ms trôi qua kể từ khi hệ thống khởi động tới thời điểm hiện tại, kết quả sẽ ra được con số rất lớn và chia lấy số dư cho 5000 sẽ ra được 1 con số từ 0-4999, cho luồng tiêu thụ này ngủ trong khoảng thời gian đó.
}
}

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; // lưu mục quản của 2 nhà sx vào 2 biến ProducerHandle1, ProducerHandle2
HANDLE ConsumerHandle1, ConsumerHandle2; //lưu mục quản của 2 nhà tiêu thụ

DWORD ProducerID1, ProducerID2; // mã số định danh của luồng sản xuất
DWORD ConsumerID1, ConsumerID2; // mã số định danh của luồng tiêu thụ

// 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);
//tạo 1 luồng sản xuất, luồng này sẽ lấy giá trị trả về của hàm Producer và được ép kiểu (LPTHREAD_START_ROUTINE), số 0 tiếp theo chỉ ra hàm Producer ko có tham biến, số 4 chỉ ra luồng vừa tạo sẽ không chạy mà ngủ luôn, &ProducerID1 chỉ ra luồng sẽ có mã số định danh là ProducerID1
// sau khi làm lệnh này, sẽ có 2 luồng, luồng ctrinh này và luồng producer
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);
//0: luồng tiêu thụ vận hành ngay, ko ngủ

ConsumerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer,
0, 0, &ConsumerID2);
while(1){
printf("\n- Nhap P/p de san xuat, 0 de ket thuc:”);
//P đánh thức nhà sx1, p sx2
switch (getch()){//biết người sử dụng bấm gì
case 'P':
ResumeThread(ProducerHandle1); //đánh thức luồng 1
break;
case 'p':
ResumeThread(ProducerHandle2);//đánh thức luồng 2
break;
case '0':
CloseHandle(ProducerHandle1);// hủy đối tượng(ở đây là luồng) có mục quản
CloseHandle(ProducerHandle2);
CloseHandle(ConsumerHandle1);
CloseHandle(ConsumerHandle2);
return 0;
}
Sleep(1);// ngủ 1 ms, tức là luồng chính sẽ trễ 1 chút để sx cho xong(chờ in tăng lên 1) rồi mới showbuffer ra
ShowBuffer();
}
}

Thank bạn nhiều.

NguyenVietHung (102C)

Tổng số bài gửi : 48
Join date : 21/02/2011

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  LuongThiXuanYen (102C) 22/4/2011, 23:51

NguyenQuocHien(102C) đã viết:// Các bạn chịu khó đọc rồi xem có bổ sung gì không nha, đoạn chương trình này công nhận là rắc rối thiệt

#include <stdio.h>
#include <conio.h>
#include <windows.h> // lập trình đa luồng đồng hành, sử dụng được hàm win32 API

#define BUFFER_SIZE 10 // định nghĩa một buffer có số khoang chứa là 10

int buffer[BUFFER_SIZE];
int in=0; // biến in chứa giá trị chỉ vị trí xếp sản phẩm vào
int out=0;// biến out chứa giá trị chỉ vị trí lấy sản phẩm ra

int nextProduced=1;// biến trung gian, chứa số hiệu sản phẩm đầu tiên

void Producer(){ // hàm sản xuất
while (1){
// ... Sản xuất (nextProduced)
while(((in+1)%BUFFER_SIZE)==out);// khoang chứa đầy thì quẩn tại đây
buffer[in]=nextProduced++; // cho sản phẩm vào mảng tại vị trí in
in=(in+1)%BUFFER_SIZE; //sau khi chèn sản phẩm vào mảng, tăng in lên 1, nếu in đang nằm ở vị trí cuối mảng sẽ nhảy về đầu mảng
SuspendThread(GetCurrentThread()); //getcureentthred: hàm của thư viện win32 API, trả về giá trị mục quản của luồng hiện hành, vd: 1700. SuspendThread(): ngừng luồng có mục quản là giá trị trong ngoặc, vd: SuspendThread(1700) ngừng luồng có mục quản 1700
}
}

void Consumer(){
int nextConsumed; // biến chứa sản phẩm được tiêu thụ
while (1){
while(in==out); //trong khoang chứa hết sản phẩm thì quẩn tại đây
nextConsumed=buffer[out]; //sản phẩm ở vị trí buffer out được đưa vào biến netxconsumed
out=(out+1)%BUFFER_SIZE;//out tăng lên 1, nếu out đang nằm ở cuối mảng thì nhảy lên đầu mảng
// ... Tiêu thụ (nextConsumed)
Sleep(GetTickCount()%5000); // hàm gettickcount() sẽ trả về thời gian tính bằng ms trôi qua kể từ khi hệ thống khởi động tới thời điểm hiện tại, kết quả sẽ ra được con số rất lớn và chia lấy số dư cho 5000 sẽ ra được 1 con số từ 0-4999, cho luồng tiêu thụ này ngủ trong khoảng thời gian đó.
}
}

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; // lưu mục quản của 2 nhà sx vào 2 biến ProducerHandle1, ProducerHandle2
HANDLE ConsumerHandle1, ConsumerHandle2; //lưu mục quản của 2 nhà tiêu thụ

DWORD ProducerID1, ProducerID2; // mã số định danh của luồng sản xuất
DWORD ConsumerID1, ConsumerID2; // mã số định danh của luồng tiêu thụ

// 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);
//tạo 1 luồng sản xuất, luồng này sẽ lấy giá trị trả về của hàm Producer và được ép kiểu (LPTHREAD_START_ROUTINE), số 0 tiếp theo chỉ ra hàm Producer ko có tham biến, số 4 chỉ ra luồng vừa tạo sẽ không chạy mà ngủ luôn, &ProducerID1 chỉ ra luồng sẽ có mã số định danh là ProducerID1
// sau khi làm lệnh này, sẽ có 2 luồng, luồng ctrinh này và luồng producer
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);
//0: luồng tiêu thụ vận hành ngay, ko ngủ

ConsumerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Consumer,
0, 0, &ConsumerID2);
while(1){
printf("\n- Nhap P/p de san xuat, 0 de ket thuc:”);
//P đánh thức nhà sx1, p sx2
switch (getch()){//biết người sử dụng bấm gì
case 'P':
ResumeThread(ProducerHandle1); //đánh thức luồng 1
break;
case 'p':
ResumeThread(ProducerHandle2);//đánh thức luồng 2
break;
case '0':
CloseHandle(ProducerHandle1);// hủy đối tượng(ở đây là luồng) có mục quản
CloseHandle(ProducerHandle2);
CloseHandle(ConsumerHandle1);
CloseHandle(ConsumerHandle2);
return 0;
}
Sleep(1);// ngủ 1 ms, tức là luồng chính sẽ trễ 1 chút để sx cho xong(chờ in tăng lên 1) rồi mới showbuffer ra
ShowBuffer();
}
}
Vì Ngồi xa mình không thấy rõ, cũng chưa hiểu lắm. Cám ơn bạn, bài viết của bạn rất đầy đủ. Giờ thì mình hiểu hơn rồi. Thanks !
LuongThiXuanYen (102C)
LuongThiXuanYen (102C)

Tổng số bài gửi : 39
Join date : 16/02/2011

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  BuiQuocDung14 (102c) 23/4/2011, 00:20

cảm ơn bạn nhiều nha!
chúc các bạn học thật tốt

BuiQuocDung14 (102c)

Tổng số bài gửi : 27
Join date : 17/02/2011

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  TranDinhHuan (102C) 25/4/2011, 17:38

Thank anh Hien nha!
TranDinhHuan (102C)
TranDinhHuan (102C)

Tổng số bài gửi : 34
Join date : 17/02/2011
Age : 35

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  BuiThiLanChi (102C) 25/4/2011, 18:41

cám ơn bạn nhe
BuiThiLanChi (102C)
BuiThiLanChi (102C)

Tổng số bài gửi : 73
Join date : 16/02/2011
Age : 34
Đến từ : Cần Thơ

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  huynhthanhphong(102c) 25/4/2011, 19:38

cảm ơn các bạn nha, mình cũng nghiên cứu mấy ngày rồi mà sao chưa hiểu, hix

huynhthanhphong(102c)

Tổng số bài gửi : 29
Join date : 23/02/2011

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  NguyenAnhNgoc56 (102C) 26/4/2011, 09:05

cám ơn bài viết của bạn nhiều, hôm đó mình ghi không kịp còn thiếu vài chỗ

NguyenAnhNgoc56 (102C)

Tổng số bài gửi : 41
Join date : 17/02/2011

Về Đầu Trang Go down

Giải thích code cho vấn đề sản xuất tiêu thụ Empty Re: Giải thích code cho vấn đề sản xuất tiêu thụ

Bài gửi  Sponsored content


Sponsored content


Về Đầu Trang Go down

Về Đầu Trang

- Similar topics

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