Thảo luận Bài 5 (Đa luồng)
+70
lengocthuthao89 (i11c)
dongocthien (I11C)
PhamThiHoa-I91C
nguyenduc_gia.18(I11c)
LeMinhDuc (I11C)
HuynhVanNhut (I11C)
PhamDuyPhuong87(I11C)
tranleanhngoc88(i11c)
LeThiThuyDuong (I11C)
lamhuubinh(I91C)
BuiVanHoc(I11C)
DangMinhQuang(I11C)
ThanhThao04(I11C)
LeMInhTien(I11C)
TRANTHINHPHAT (I11C)
NguyenNgocMyTien(I11C)
DaoVanHoang (I11C)
NguyenTrongHuy(I11C)
chauchanduong (I11C)
ngocquynh2091(i11C)
08H1010052
HoangNgocQuynh(I11C)
DuongKimLong(I111C)
NguyenDoTu (I11C)
VOTHANHTRUNG(I11C)
TranMinh (I11C)
hoangdung_I91C
TranHaDucHuy (I11c)
PhamAnhKhoa(I11C)
TranVuThuyVan_(I11C)
DuongTrungTinh(I11C)
NguyThiGai (I11C)
TranHuynhDucHanh(I11C)
XuanThai_I11C
Nguyenminhduc (I11C)
NguyenDinhHop (I11C)
AnhDuong
NguyenTienPhong083 (I11C)
tranphanhieu36_i11c
DuongThiHien (I11c)
DangNgocMinh(I11C)
TrinhThiPhuongThaoI11C
NguyenThiThanhThuy(I11C)
minhgiangbc
LeTanDat (I11C)
nguyenminhlai.(I11C)
nguyenthanhphuong(I11C)
LaVanKhuong (I11C)
n.t.tuyet.trinh90 (I11C)
vohongcong(I111C)
DaoQuangSieu (I11C)
NgoLeYen48(I11C)
HoiHoangHongVu I11C
ToThiThuyTrang (I11C)
hoangquocduy.i11c
NguyenHaThanh97 (I11C)
DoThuyTien16 (I11C)
NgoDucTuan (I11C)
thanhnam06511c
VoMinhHoang (I11C)
NguyenHoangKimVu (I11C)
TruongThiThuyPhi(I11C)
PhamHuyHoang (I11C)
buithithudung24 (i11c)
nguyenthithuylinh (I11C)
NguyenThanhTam (I11C)
Tranvancanh(I11C)
NguyenXuanTri28
tranvantoan83(I11c)
Admin
74 posters
Trang 3 trong tổng số 6 trang
Trang 3 trong tổng số 6 trang • 1, 2, 3, 4, 5, 6
Y nghĩa 1 vai ham trong bài toán
Cảm ơn bạn đã giải thích code này, mình cũng đang tìm cái này vì có một số dòng lệnh chưa hiểu rõ, hi vọng học xong môn này mình có thể ứng dụng thực tiễn nhiều hơnminhgiangbc đã viết:Y nghĩa 1 vai ham trong bài toán
#include <stdio.h> -->khai báo
#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){
// ... (nextProduced) quá trình tạo ra 1 sản phẩm
while(((in+1)%BUFFER_SIZE)==out); ---> vòng lặp quẩn tại đây cho đến khi có 1 chỗ trống trong bộ đệm hay ngăn chứa sản phẩm… khi vòng lặp while kết thúc --> có 1 chỗ trống để chèn sản phẩm vô
buffer[in]=nextProduced++; --> chèn sản phẩm vô ngăn chứa
in=(in+1)%BUFFER_SIZE; --> tìm vị trí khác để Producer chèn thêm sản phầm vào
SuspendThread(GetCurrentThread());lấy luồng hiện hành, SuspendThread hàm API dùng để tạo ngưng 1 luồng.
}
}
void Consumer(){
int nextConsumed;
while (1){
while(in==out); --> vòng lặp quẩn tại đây khi các ngăn chứa sản phầm đều trống
------vòng lặp while thoát khi có 1 ngăn chứa sản phầm---------
nextConsumed=buffer[out]; --> lấy sản phẩm ra khỏi ngăn
out=(out+1)%BUFFER_SIZE; --> tìm vị trí khác để Consumer lấy sản phẩm nếu out đang nằm ở cuối mảng thì out sẽ trở về đầu mảng
// ... (nextConsumed) ----quá trình tiêu thụ sàn phẩm-----
Sleep(GetTickCount()%5000); --> hàm API đưa luồng vào trạng thái ngủ trong khi chờ Producer sản xuất thêm sản phầm,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, chia lấy số dư cho 5000 sẽ ra được 1 con số từ 0-4999, cho luồng tiêu thụ này tạm dừng trong khoảng thời gian đó.
}
}
void ShowBuffer(){ // In nộii 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; --> biến Handle chứa mục quản NSX
HANDLE ConsumerHandle1, ConsumerHandle2; --> biến Handle chứa mục quản NTT
DWORD ProducerID1, ProducerID2; --> chứa ID NSX
DWORD ConsumerID1, ConsumerID2; --> chứa ID NTT
// 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); //khởi tạo NSX với các thông tin: Producer, ID, số 4 biểu thị trạng thái của Producer lúc khởi tạo là trạng thái luôn luôn ngủ
ProducerHandle2=CreateThread(0,0,
(LPTHREAD_START_ROUTINE)Producer,0, 4, &ProducerID2); // tuong tu
// tao 2 luồng tiêu thụ trong trang thái ngay
ConsumerHandle1=CreateThread(0,0,(LPTHREAD_START_ROUTINE)Consumer,0, 0, &ConsumerID1); //khởi tạo NTT với các thông tin: Consumer, ID, số 0 biểu thị trạng thái của Producer lúc khởi tạo: trạng thái luôn luôn thức.
ConsumerHandle2=CreateThread(0,0,(LPTHREAD_START_ROUTINE)Consumer,0, 0, &ConsumerID2); //tuong tu
while(1){
printf("\n- Nhấn P/p để sản xuất,0 để kết thúc:”);
switch (getch()){
case 'P':
ResumeThread(ProducerHandle1); //đánh thức Producer lúc này đang ở trạng thái ngủ
break;
case 'p':
ResumeThread(ProducerHandle2); ///đánh thức Producer lúc này đang ở trạng thái ngủ
break;
case '0': /// giải phóng Producer và Consumer khỏi bộ nhớ
CloseHandle(ProducerHandle1);
CloseHandle(ProducerHandle2);
CloseHandle(ConsumerHandle1);
CloseHandle(ConsumerHandle2);
return 0;
}
Sleep(1); --> ngủ trong khoảng 1mns
ShowBuffer(); -->kết quả sau khi sản xuất tiêu thụ, khi đang show thì không sx, không tiêu thụ
}
}
NgoDucTuan (I11C)- Tổng số bài gửi : 52
Join date : 31/08/2011
Re: Thảo luận Bài 5 (Đa luồng)
NguyenXuanTri28 đã viết:Những lợi ích của công nghệ đa luồng
Khả năng đáp ứng (Responsiveness) tốt hơn: Trong khi một luồng bị ách hoặc quá bận, luồng khác vẫn vận hành bình thường (Luồng chính của trình duyệt vẫn tương tác với người dùng trong khi dữ liệu được lấy về).
Ví dụ: Các cô ở tổng đài 108 là các luồng. Khi khách hàng điện thoại hỏi 108. Nếu chỉ có 1 cô phải trực 10 máy điện thoại thì khi chỉ có 1 cuộc điện thoại gọi đến thì cô sẽ trả lời tốt nhưng khi có khoảng 3 cuộc điện thoại trở lên thì cô không thể trả lời được kịp hết.
Nếu có nhiều cô cùng trực điện thoại thì lúc đó sẽ tốt hơn, đáp ứng được nhu cầu của khách hàng khi họ gọi đến .
Nếu trong thời điểm đó khách hàng thứ hai gọi 108, thì một trong các cô (cô thứ 2) còn lại sẽ trả lời cho khách hàng.
Chia sẻ tài nguyên (Resource Sharing): Theo mặc định, các luồng có thể dùng chung bộ nhớ và tài nguyên của luồng cha. Vài luồng cùng vận hành trong 1 vùng địa chỉ, do đó dễ dùng chung tài nguyên hơn so với trường hợp đa tiến trình.
Ví dụ: Trong nhà ta có kệ sách, tivi, xe gắn máy, ... mọi người trong nhà có thể dùng chung sách, tivi, xe máy.
Tiết kiệm (Economy): Cấp phát bộ nhớ và tài nguyên cho tiến trình là công việc tốn kém. Do luồng chung tài nguyên với cha và các luồng khác, việc tạo lập và chuyển ngữ cảnh cũng nhanh hơn (Solaris 2: Tạo tiến trình chậm hơn 30 lần, Chuyển ngữ cảnh chậm hơn 5 lần).
Ví dụ: Các bạn trong lớp là các luồng đang dùng chung một cái bảng, ai cần ghi thi ghi, ai cần thì chụp hình về xem
Tận dụng được thế mạnh của kiến trúc đa xử lý: Đa luồng làm tăng tính song song trên hệ máy nhiều CPU. Mỗi luồng có thể chạy bởi CPU riêng.
Có 1 điều này, trong buổi học, Thầy đã cung cấp cho chúng ta thêm lợi ích của đa luồng:
Lập trình đa luồng nhanh và dễ hơn là lập trình đa tiến trình.
DuongThiHien (I11c)- Tổng số bài gửi : 7
Join date : 26/08/2011
Re: Thảo luận Bài 5 (Đa luồng)
câu trả lời này mình đọc được trong bài của khóa trước xin post vào đây để mọi người tham khảonguyenminhlai.(I11C) đã viết:ToThiThuyTrang (I11C) đã viết:1- Lợi thế của một ứng dụng Multithreaded
* Cải thiện hiệu suất và đồng thời
Đối với các ứng dụng nhất định, hiệu quả và đồng thời có thể được cải thiện bằng cách sử dụng đa luồng và multicontexting với nhau. Trong các ứng dụng khác, hiệu suất có thể không bị ảnh hưởng hoặc thậm chí bị suy thoái bằng cách sử dụng đa luồng và multicontexting với nhau. Làm thế nào hiệu suất bị ảnh hưởng phụ thuộc vào ứng dụng của bạn.
* Đơn giản hóa mã hóa các cuộc gọi thủ tục từ xa và các cuộc hội thoại
Trong một số ứng dụng nó được dễ dàng hơn để mã cuộc gọi thủ tục khác nhau từ xa và các cuộc hội thoại trong chủ đề riêng biệt hơn để quản lý chúng từ cùng một thread.
* Đồng thời tiếp cận với nhiều ứng dụng
BEA Tuxedo khách hàng của bạn có thể được kết nối với nhiều ứng dụng cùng một lúc.
* Giảm số lượng máy chủ cần thiết
Bởi vì một máy chủ có thể gửi chủ đề dịch vụ nhiều, số lượng máy chủ để bắt đầu cho ứng dụng của bạn bị giảm. Khả năng này cho nhiều đề cử đặc biệt hữu ích cho các máy chủ thoại, nếu không phải được dành riêng cho một khách hàng cho toàn bộ thời gian của cuộc hội thoại.
Đối với các ứng dụng, trong đó chủ đề của khách hàng được tạo ra bởi Microsoft Internet Information Server API hoặc giao diện Netscape Enterprise Server (có nghĩa là, các NSAPI), việc sử dụng nhiều đề tài là điều cần thiết nếu bạn muốn có được những lợi ích đầy đủ khả năng bởi những công cụ này.
2- Nhược điểm của một ứng dụng Multithreaded
* Khó khăn của việc viết mã
ứng dụng Multithreaded và multicontexted không dễ dàng để viết. Chỉ lập trình viên có kinh nghiệm nên thực hiện mã hóa cho các loại ứng dụng.
• Khó khăn của gỡ rối
Đó là khó khăn hơn nhiều để tái tạo một lỗi trong ứng dụng đa luồng hoặc multicontexted hơn là để làm như vậy trong một ứng dụng đơn luồng đơn contexted,. Kết quả là, nó là khó khăn hơn, trong trường hợp trước đây, để xác định và xác minh nguyên nhân gốc rễ khi lỗi xảy ra.
• Khó khăn của việc quản lý đồng thời
Các nhiệm vụ quản lý tương tranh giữa các chủ đề rất khó khăn và có tiềm năng để giới thiệu những vấn đề mới vào ứng dụng.
• Khó khăn thử nghiệm
Kiểm tra một ứng dụng đa luồng là khó khăn hơn thử nghiệm một ứng dụng đơn luồng, vì khuyết tật này thường liên quan đến thời gian và khó khăn hơn để sinh sản.
• Khó khăn của porting mã hiện tại
Code hiện tại thường đòi hỏi quan trọng tái kiến trúc để tận dụng đa luồng. Các lập trình viên cần phải:
o Hủy bỏ các biến tĩnh
o Thay thế bất kỳ chức năng cuộc gọi mà không phải là thread-safe
o Thay thế các mã khác mà không phải là thread-safe
Bởi vì các cảng đã hoàn thành phải được kiểm tra và tái kiểm tra, công việc yêu cầu một cổng đa luồng ứng dụng là đáng kể.
Vậy bạn cho mình biết cụ thể là mục đích chính của ứng dụng Multithreaded dùng để làm gì, và nó ứng dụng cho việc gì ?
Lợi thế của một ứng dụng Multithreaded :
* Cải thiện hiệu suất và đồng thời :
Đối với các ứng dụng nhất định, hiệu quả và đồng thời có thể được cải thiện bằng cách sử dụng đa luồng và multicontexting với nhau. Trong các ứng dụng khác, hiệu suất có thể không bị ảnh hưởng hoặc thậm chí bị suy thoái bằng cách sử dụng đa luồng và multicontexting với nhau. Làm thế nào hiệu suất bị ảnh hưởng phụ thuộc vào ứng dụng của bạn.
* Đơn giản hóa mã hóa các cuộc gọi thủ tục từ xa và các cuộc hội thoại
Trong một số ứng dụng nó được dễ dàng hơn để mã cuộc gọi thủ tục khác nhau từ xa và các cuộc hội thoại trong chủ đề riêng biệt hơn để quản lý chúng từ cùng một thread.
* Đồng thời tiếp cận với nhiều ứng dụng
BEA Tuxedo khách hàng của bạn có thể được kết nối với nhiều ứng dụng cùng một lúc.
* Giảm số lượng máy chủ cần thiết
Bởi vì một máy chủ có thể gửi chủ đề dịch vụ nhiều, số lượng máy chủ để bắt đầu cho ứng dụng của bạn bị giảm. Khả năng này cho nhiều đề cử đặc biệt hữu ích cho các máy chủ thoại, nếu không phải được dành riêng cho một khách hàng cho toàn bộ thời gian của cuộc hội thoại.
Đối với các ứng dụng, trong đó chủ đề của khách hàng được tạo ra bởi Microsoft Internet Information Server API hoặc giao diện Netscape Enterprise Server (có nghĩa là, các NSAPI), việc sử dụng nhiều đề tài là điều cần thiết nếu bạn muốn có được những lợi ích đầy đủ khả năng bởi những công cụ này.
Còn về ứng dụng thì mình thấy trong java nhiều người hay nói phần này mình không rành nên không dám múa rìu qua mắt thợ
Được sửa bởi DangNgocMinh(I11C) ngày 9/10/2011, 15:58; sửa lần 1.
DangNgocMinh(I11C)- Tổng số bài gửi : 26
Join date : 31/08/2011
Một số ví dụ về nguyên lý tập luồng và ứng dụng !
VD1. Trang bị sẵn cho 1 nhóm chiến sĩ gồm áo giáp, súng, quân phục...(Mỗi chiến sĩ giống nhưn một luồng con; các chiến sĩ dùng chung những kỷ luật chung của quân đội cũng như các luồng dùng chung code,data,file ; áo giáp, súng, quân phục là những trang bị dành riêng cho mỗi chiến sĩ quản lý và sử dụng cũng như stack và registers cấp riêng cho mỗi luồng) Và nhóm chiến sĩ này khi chưa có địch đến thì nghỉ chờ ( nhưng đã sẵn sàng chiến đấu ) . Khi có một tên địch đến thì điều 1 chiến sĩ ra đánh, khi đánh xong rồi thì chiến sĩ này quay về trạng thái sẵn sàng và tiếp tục chờ. Nếu có nhiều tên địch cùng lúc thì có nhiều chiến sĩ ra chiến đấu cùng lúc. Nếu số địch nhiều hơn số chiến sĩ thì trong một thời điểm mỗi chiến sĩ vẫn sẽ chiến đấu với 1 một tên địch, và khi đánh xong rồi thì đánh tiếp tên khác.
VD2. Về thực tiễn việc công ty mạng Phương Nam. Giám đốc công ty này bày tỏ về phần mềm ứng dụng hỗ trợ tìm việc rất hay với thầy, mỗi cá nhân muốn tìm việc thì ghi thông tin của mình vào cơ sở dữ liệu ở đó, và mỗi công ty tổ chức cần tìm nhân sự thì vào cơ sở dữ liệu ở đó để lấy thông tin và tuyển người. Nhưng có 1 vấn đề là khi ứng dụng này đưa vào sử dụng nếu bằng hoặc hơn 6 người cùng đăng ký thông tin cá nhân cùng lúc thì máy chủ bị treo phải tắt đi và khởi động lại. Thầy nghe xong đoán ngay là mỗi lần bị vấn đề như thế thì có tới hơn 5 ứng dụng giống nhau quản lý thông tin này đang chạy trên màn hình máy chủ. Và quả đúng như thế bởi vì thầy biết trước đây người ta lập trình bằng CGI viết bằng C, hỗ trợ lập trình đa tiến trình (mỗi cửa sổ chương trình là một tiến trình, chương trình nào có thể chạy nhiều cửa sổ cùng lúc là chương trình có hỗ trợ đa tiến trình). Thầy đã giải quyết một cách dễ dàng bằng cách lập trình lại ứng dụng bằng ASP và đã thành công giải quyết được vấn đề đó. Thành công tốt hơn vì ASP là đa luồng còn CGI là đa tiến trình. Đa luồng sẽ tốt hơn đa tiến trình.
VD3. :tổng đài điện thoại 108 , có nhiều nhân viên trực điện thoại ( nhân viên là các luồng con ) , số nhân viên tương ứng với số luồng trong tập luồng , cùng làm việc trong 1 văn phòng ( cùng chung 1 bộ nhớ ) , mỗi nhân viên trực 1 điện thoại ( tức là mỗi luồng điều khiển 1 CPU ), do đó luồng có khả năng đáp ứng cao , khi không có cuộc gọi đến của khách hàng -> nhân viên không làm việc ( luồng đang ở trạng thái ngủ ), khi có cuộc gọi đến của khách hàng -> nhân viên trả lời cuộc gọi (luồng được đánh thức và đưa vào vận hành ) -> kết thúc cuộc gọi của khách hàng , nhân viên được nghỉ ( tức là luồng quay trạng thái ban đầu , trạng thái ngủ ) .
VD4. Web Server, Database Server cũng làm việc theo nguyên lý tập luồng này
Mình chỉ trình bày những ví dụ được nghe thầy giảng trên lớp theo cách mình hiểu. Mong thầy và các bạn góp ý để mình hiểu rõ hơn !
VD2. Về thực tiễn việc công ty mạng Phương Nam. Giám đốc công ty này bày tỏ về phần mềm ứng dụng hỗ trợ tìm việc rất hay với thầy, mỗi cá nhân muốn tìm việc thì ghi thông tin của mình vào cơ sở dữ liệu ở đó, và mỗi công ty tổ chức cần tìm nhân sự thì vào cơ sở dữ liệu ở đó để lấy thông tin và tuyển người. Nhưng có 1 vấn đề là khi ứng dụng này đưa vào sử dụng nếu bằng hoặc hơn 6 người cùng đăng ký thông tin cá nhân cùng lúc thì máy chủ bị treo phải tắt đi và khởi động lại. Thầy nghe xong đoán ngay là mỗi lần bị vấn đề như thế thì có tới hơn 5 ứng dụng giống nhau quản lý thông tin này đang chạy trên màn hình máy chủ. Và quả đúng như thế bởi vì thầy biết trước đây người ta lập trình bằng CGI viết bằng C, hỗ trợ lập trình đa tiến trình (mỗi cửa sổ chương trình là một tiến trình, chương trình nào có thể chạy nhiều cửa sổ cùng lúc là chương trình có hỗ trợ đa tiến trình). Thầy đã giải quyết một cách dễ dàng bằng cách lập trình lại ứng dụng bằng ASP và đã thành công giải quyết được vấn đề đó. Thành công tốt hơn vì ASP là đa luồng còn CGI là đa tiến trình. Đa luồng sẽ tốt hơn đa tiến trình.
VD3. :tổng đài điện thoại 108 , có nhiều nhân viên trực điện thoại ( nhân viên là các luồng con ) , số nhân viên tương ứng với số luồng trong tập luồng , cùng làm việc trong 1 văn phòng ( cùng chung 1 bộ nhớ ) , mỗi nhân viên trực 1 điện thoại ( tức là mỗi luồng điều khiển 1 CPU ), do đó luồng có khả năng đáp ứng cao , khi không có cuộc gọi đến của khách hàng -> nhân viên không làm việc ( luồng đang ở trạng thái ngủ ), khi có cuộc gọi đến của khách hàng -> nhân viên trả lời cuộc gọi (luồng được đánh thức và đưa vào vận hành ) -> kết thúc cuộc gọi của khách hàng , nhân viên được nghỉ ( tức là luồng quay trạng thái ban đầu , trạng thái ngủ ) .
VD4. Web Server, Database Server cũng làm việc theo nguyên lý tập luồng này
Mình chỉ trình bày những ví dụ được nghe thầy giảng trên lớp theo cách mình hiểu. Mong thầy và các bạn góp ý để mình hiểu rõ hơn !
tranphanhieu36_i11c- Tổng số bài gửi : 31
Join date : 25/08/2011
Re: Thảo luận Bài 5 (Đa luồng)
Trình bày khái niệm luồng, cho ví dụ minh họa, so sánh với khái niệm tiến trình truyền thống.
Khái nệm Luồng :
Luồng (Thread) còn gọi là tiến trình nhẹ (LWP Light Weight Process) , một đơn vị co bản sử dụng CPU, nó hình thành gồm : một định danh luồng (thread ID), một bộ đếm chương trình , tập thanh ghi và ngăn xếp. Nó chia sẻ với các luồng khác thuộc cùng một quá trình phần mã, phần dữ liệu và tài nguyên hệ điều hành như các tập tin đang mở và các tín hiệu. Một tiến trình truyền thống (hay tiến trình nặng) có một luồng điều khiển đơn. Nếu tiến trình có nhiều luồng điều khiển nó có thể thực hiện nhiều công việc ở cùng một thời điểm.
Ví dụ : mỗi bạn trong lớp là một tiểu trình (luồng) và lớp là một tiến trình.
+ Luồng mặc dù ở bên trong tiến trình nhưng hệ diều hành vẫn có thể truy xuất được vào.
+ Các phiên bản của HĐH đều hỗ trợ đa luồng bên trong tiến trình truyền thống.
+ Các luồng có thể dùng chung bộ nhớ và tài nguyên của tiến trình cha, vài luông có thể vận hành trong một địa chỉ do đó chúng có khả năng chúng có khả năng chia sẻ tài nguyên, dùng chung tài nguyên dễ dàng hơn so với trường hợp đa tiến trình truyền thống.
+ Nhiều luồng có thể dùng chung mã chương trình
Ví dụ : Ở lớp I11C có hai loại luồng là luồng Giảng viên (đơn luồng ) và luồng Sinh viên (đa luồng) , các bạn sinh viên trong lớp là luồng dùng chung code do Giảng viên đưa ra
Khái nệm Luồng :
Luồng (Thread) còn gọi là tiến trình nhẹ (LWP Light Weight Process) , một đơn vị co bản sử dụng CPU, nó hình thành gồm : một định danh luồng (thread ID), một bộ đếm chương trình , tập thanh ghi và ngăn xếp. Nó chia sẻ với các luồng khác thuộc cùng một quá trình phần mã, phần dữ liệu và tài nguyên hệ điều hành như các tập tin đang mở và các tín hiệu. Một tiến trình truyền thống (hay tiến trình nặng) có một luồng điều khiển đơn. Nếu tiến trình có nhiều luồng điều khiển nó có thể thực hiện nhiều công việc ở cùng một thời điểm.
Ví dụ : mỗi bạn trong lớp là một tiểu trình (luồng) và lớp là một tiến trình.
+ Luồng mặc dù ở bên trong tiến trình nhưng hệ diều hành vẫn có thể truy xuất được vào.
+ Các phiên bản của HĐH đều hỗ trợ đa luồng bên trong tiến trình truyền thống.
+ Các luồng có thể dùng chung bộ nhớ và tài nguyên của tiến trình cha, vài luông có thể vận hành trong một địa chỉ do đó chúng có khả năng chúng có khả năng chia sẻ tài nguyên, dùng chung tài nguyên dễ dàng hơn so với trường hợp đa tiến trình truyền thống.
+ Nhiều luồng có thể dùng chung mã chương trình
Ví dụ : Ở lớp I11C có hai loại luồng là luồng Giảng viên (đơn luồng ) và luồng Sinh viên (đa luồng) , các bạn sinh viên trong lớp là luồng dùng chung code do Giảng viên đưa ra
NguyenTienPhong083 (I11C)- Tổng số bài gửi : 37
Join date : 26/08/2011
Age : 36
Tóm tắt những câu hỏi chính của công nghệ Đa Luồng bằng hình ành
1 - Những lợi ích của công nghệ Đa Luồng
AnhDuong- Tổng số bài gửi : 8
Join date : 30/08/2011
Hướng dẫn tạo luồng bằng JAVA
Giới thiệu Luồng Java
Như chúng ta đã thấy, hỗ trợ cho luồng có thể được cung cấp tại cấp người dùng với một thư viện như Pthread. Hơn nữa, hầu hết hệ điều hành cung cấp sự hỗ trợ cho luồng tại cấp nhân. Java là một trong số nhỏ ngôn ngữ cung cấp sự hỗ trợ tại cấp ngôn ngữ cho việc tạo và quản lý luồng. Tuy nhiên, vì các luồng được quản lý bởi máy ảo Java, không bởi một thư viện cấp người dùng hay nhân, rất khó để phân cấp luồng Java như cấp độ người dùng hay cấp độ nhân. Trong phần này chúng ta trình bày các luồng Java như một thay đổi đối với mô hình người dùng nghiêm ngặt hay mô hình cấp nhân.
Tất cả chương trình tạo ít nhất một luồng điều khiển đơn. Thậm chí một chương trình Java chứa chỉ một phương thức main chạy như một luồng đơn trong máy ảo Java. Ngoài ra, Java cung cấp các lệnh cho phép người phát triển tạo và thao tác các luồng điều khiển bổ sung trong chương trình.
Cách tạo luồng trong Java
Một cách để tạo một luồng rõ ràng là tạo một lớp mới được phát sinh từ lớp Thread và viết đè phương thức run của lớp Thread. Tiếp cận này được hiển thị trong hình sau, ấn bản Java của chương trình đa luồng xác định tổng các số nguyên không âm. Một đối tượng của lớp phát sinh sẽ chạy như một luồng điều khiển đơn trong máy ảo Java. Tuy nhiên, tạo một đối tượng được phát sinh từ lớp Thread không tạo một luồng mới, trái lại phương thức start mới thật sự tạo luồng mới. Gọi phương thức start cho đối tượng mới thực hiện hai thứ:
1) Nó cấp phát bộ nhớ và khởi tạo một luồng mới trong máy ảo Java.
2) Nó gọi phương thức run, thực hiện luồng thích hợp để được chạy bởi máy ảoJava. (Chú ý, không thể gọi phương thức run trực tiếp, gọi phương thức start sẽ gọi phương thức run).
Để hiếu rõ hơn về cách tạo luồng trong Java mình xin giởi thiệu ví dụ hàm tính tổng các số nguyên không âm
Class Summation extends Thread
{
public Summation (int n){
upper = n;
}
public void run(){
int sum = 0;
if (upper>0){
for(int i = 1; i<= upper; i++){
sum+=i;
}
System.out.println(“The sum of ”+upper+ “ is “ + sum);
}
private int upper;
}
public class ThreadTester
{
public static void main(String args[]){
if(args.length>0){
if(Integer.parseInt(args[0])<0)
System.err.println(args[0] + “ must be >= 0.”);
else{
Summation thrd = new Summation
(Integer.parseInt(args[0]));
Thrd.start();
}
}
Else
System.out.println(“Usage: summation < integer value”);
}
}
Khi chương trình tính tổng thực thi, hai luồng được tạo bởi JVM. Luồng đầu tiên là luồng được nối kết với ứng dụng-luồng này bắt đầu thực thi tại phương thức main. Luồng thứ hai là luồng Summation được tạo rõ ràng với phương thức start.Luồng Summation bắt đầu thực thi trong phương thức run của nó. Luồng kết thúc khi nó thoát khỏi phương thức run của nó.
Như chúng ta đã thấy, hỗ trợ cho luồng có thể được cung cấp tại cấp người dùng với một thư viện như Pthread. Hơn nữa, hầu hết hệ điều hành cung cấp sự hỗ trợ cho luồng tại cấp nhân. Java là một trong số nhỏ ngôn ngữ cung cấp sự hỗ trợ tại cấp ngôn ngữ cho việc tạo và quản lý luồng. Tuy nhiên, vì các luồng được quản lý bởi máy ảo Java, không bởi một thư viện cấp người dùng hay nhân, rất khó để phân cấp luồng Java như cấp độ người dùng hay cấp độ nhân. Trong phần này chúng ta trình bày các luồng Java như một thay đổi đối với mô hình người dùng nghiêm ngặt hay mô hình cấp nhân.
Tất cả chương trình tạo ít nhất một luồng điều khiển đơn. Thậm chí một chương trình Java chứa chỉ một phương thức main chạy như một luồng đơn trong máy ảo Java. Ngoài ra, Java cung cấp các lệnh cho phép người phát triển tạo và thao tác các luồng điều khiển bổ sung trong chương trình.
Cách tạo luồng trong Java
Một cách để tạo một luồng rõ ràng là tạo một lớp mới được phát sinh từ lớp Thread và viết đè phương thức run của lớp Thread. Tiếp cận này được hiển thị trong hình sau, ấn bản Java của chương trình đa luồng xác định tổng các số nguyên không âm. Một đối tượng của lớp phát sinh sẽ chạy như một luồng điều khiển đơn trong máy ảo Java. Tuy nhiên, tạo một đối tượng được phát sinh từ lớp Thread không tạo một luồng mới, trái lại phương thức start mới thật sự tạo luồng mới. Gọi phương thức start cho đối tượng mới thực hiện hai thứ:
1) Nó cấp phát bộ nhớ và khởi tạo một luồng mới trong máy ảo Java.
2) Nó gọi phương thức run, thực hiện luồng thích hợp để được chạy bởi máy ảoJava. (Chú ý, không thể gọi phương thức run trực tiếp, gọi phương thức start sẽ gọi phương thức run).
Để hiếu rõ hơn về cách tạo luồng trong Java mình xin giởi thiệu ví dụ hàm tính tổng các số nguyên không âm
Class Summation extends Thread
{
public Summation (int n){
upper = n;
}
public void run(){
int sum = 0;
if (upper>0){
for(int i = 1; i<= upper; i++){
sum+=i;
}
System.out.println(“The sum of ”+upper+ “ is “ + sum);
}
private int upper;
}
public class ThreadTester
{
public static void main(String args[]){
if(args.length>0){
if(Integer.parseInt(args[0])<0)
System.err.println(args[0] + “ must be >= 0.”);
else{
Summation thrd = new Summation
(Integer.parseInt(args[0]));
Thrd.start();
}
}
Else
System.out.println(“Usage: summation < integer value”);
}
}
Khi chương trình tính tổng thực thi, hai luồng được tạo bởi JVM. Luồng đầu tiên là luồng được nối kết với ứng dụng-luồng này bắt đầu thực thi tại phương thức main. Luồng thứ hai là luồng Summation được tạo rõ ràng với phương thức start.Luồng Summation bắt đầu thực thi trong phương thức run của nó. Luồng kết thúc khi nó thoát khỏi phương thức run của nó.
NguyenDinhHop (I11C)- Tổng số bài gửi : 14
Join date : 26/08/2011
Tại sao các luồng phải dùng chung một mã chương trình(code)?
*Các luồng phải dùng chung một mã chương trình vì:
- Đảm bảo tính nhất quán trong một tiến trình.
- Khi tiến trình gặp vấn đề,ta chỉ cần kiểm tra mã chương trình của luồng nhưng có thể biết lỗi mã chương trình của tất cả các luồng còn lại và sửa lỗi.
- Khi phát triển mã thì chỉ phải phát triển một mã chương trình nhưng sử dụng cho tất cả các luồng của một tiến trình.
- Đảm bảo tính nhất quán trong một tiến trình.
- Khi tiến trình gặp vấn đề,ta chỉ cần kiểm tra mã chương trình của luồng nhưng có thể biết lỗi mã chương trình của tất cả các luồng còn lại và sửa lỗi.
- Khi phát triển mã thì chỉ phải phát triển một mã chương trình nhưng sử dụng cho tất cả các luồng của một tiến trình.
Nguyenminhduc (I11C)- Tổng số bài gửi : 18
Join date : 07/09/2011
Tại sao giữa các luồng trong một tiến trình có thể chia sẻ tài nguyên dễ dang như vậy?
Việc chia sẻ tài nguyên giữa các luồng dễ dàng vì:
- Các luồng nằm chung trong một tiến trình.
- Các luồng dùng chung một mã chương trình.Vì vậy việc chia sẻ tài nguyên dễ dàng hơn do tài nguyên luồng này sử dụng cung chính là tài nguyên các luồng còn lại sử dụng.
- Các luồng nằm chung trong một tiến trình.
- Các luồng dùng chung một mã chương trình.Vì vậy việc chia sẻ tài nguyên dễ dàng hơn do tài nguyên luồng này sử dụng cung chính là tài nguyên các luồng còn lại sử dụng.
Nguyenminhduc (I11C)- Tổng số bài gửi : 18
Join date : 07/09/2011
Trình bày nguyên lý tập luồng và ví dụ minh họa?
-Tập luồng(Thread pools): khi một luồng chính tạo ra tập luồng (tập luồng bao gồm nhiều luồng con sẵn sàn chờ công việc được giao )
-Khi tiến trình cha nhận được yêu cầu công việc , thì 1 luồng con trong tập được đánh thức và đưa vào vận hành .
-vận hành xong luồng con sẽ được trả về tập luồng .
-Nếu số yêu cầu lớn hơn số luồng trong tập luồng , tiến trình cha sẽ chờ đến khi có luồng được giải phóng .
VÍ DỤ:tổng đài điện thoại 108 , có nhiều nhân viên trực điện thoại ( nhân viên là các luồng con ) , số nhân viên tương ứng với số luồng trong tập luồng , cùng làm việc trong 1 văn phòng ( cùng chung 1 bộ nhớ ) , mỗi nhân viên trực 1 điện thoại ( tức là mỗi luồng điều khiển 1 CPU ), do đó luồng có khả năng đáp ứng cao , khi không có cuộc gọi đến của khách hàng -> nhân viên không làm việc ( luồng đang ở trạng thái ngủ ), khi có cuộc gọi đến của khách hàng -> nhân viên trả lời cuộc gọi (luồng được đánh thức và đưa vào vận hành ) -> kết thúc cuộc gọi của khách hàng , nhân viên được nghỉ ( tức là luồng quay trạng thái ban đầu , trạng thái ngủ ) .
-Khi tiến trình cha nhận được yêu cầu công việc , thì 1 luồng con trong tập được đánh thức và đưa vào vận hành .
-vận hành xong luồng con sẽ được trả về tập luồng .
-Nếu số yêu cầu lớn hơn số luồng trong tập luồng , tiến trình cha sẽ chờ đến khi có luồng được giải phóng .
VÍ DỤ:tổng đài điện thoại 108 , có nhiều nhân viên trực điện thoại ( nhân viên là các luồng con ) , số nhân viên tương ứng với số luồng trong tập luồng , cùng làm việc trong 1 văn phòng ( cùng chung 1 bộ nhớ ) , mỗi nhân viên trực 1 điện thoại ( tức là mỗi luồng điều khiển 1 CPU ), do đó luồng có khả năng đáp ứng cao , khi không có cuộc gọi đến của khách hàng -> nhân viên không làm việc ( luồng đang ở trạng thái ngủ ), khi có cuộc gọi đến của khách hàng -> nhân viên trả lời cuộc gọi (luồng được đánh thức và đưa vào vận hành ) -> kết thúc cuộc gọi của khách hàng , nhân viên được nghỉ ( tức là luồng quay trạng thái ban đầu , trạng thái ngủ ) .
Nguyenminhduc (I11C)- Tổng số bài gửi : 18
Join date : 07/09/2011
Các thành phần của một luồng trong Windows
Những thành phần thông thường của một luồng gồm:
• ID của luồng định danh duy nhất luồng
• Tập thanh ghi biểu diễn trạng thái của bộ xử lý
• Ngăn xếp người dùng khi luồng đang chạy ở chế độ người dùng. Tương tự,mỗi luồng cũng có một ngăn xếp nhân được dùng khi luồng đang chạy trong chế độ nhân
• Một vùng lưu trữ riêng được dùng bởi nhiều thư viện thời gian thực và thự viện liên kết động (DLLs).
Cấu trúc dữ liệu chủ yếu của luồng gồm:
• RTHREAD (executive thread block-khối luồng thực thi).
• KTHREAD (kernel thread-khối luồng nhân).
• TEB (thread environment block-khối môi trường luồng)
Các thành phần chủ yếu của RTHREAD gồm một con trỏ chỉ tới quá trình nào luồng thuộc về và địa chỉ của thủ tục mà luồng bắt đầu điều khiển trong đó.ETHREAD cũng chứa một con trỏ chỉ tới KTHREAD tương ứng.
• KTHREAD gồm thông tin định thời và đồng bộ hóa cho luồng. Ngoài ra,KTHREAD chứa ngăn xếp nhân (được dùng khi luồng đang chạy trong chế độ nhân)và con trỏ chỉ tới TEB.
• ETHREAD và KTHREAD tồn tại hoàn toàn ở không gian nhân; điều này có nghĩa chỉ nhân có thể truy xuất chúng.
• TEB là cấu trúc dữ liệu trong không gian người dùng được truy xuất khi luồng đang chạy ở chế độ người dùng. Giữa những trường khác nhau, TEB chứa ngăn xếp người dùng và một mảng cho dữ liệu đặc tả luồng (mà Windows gọi là lưu trữ cục bộ luồng)
• ID của luồng định danh duy nhất luồng
• Tập thanh ghi biểu diễn trạng thái của bộ xử lý
• Ngăn xếp người dùng khi luồng đang chạy ở chế độ người dùng. Tương tự,mỗi luồng cũng có một ngăn xếp nhân được dùng khi luồng đang chạy trong chế độ nhân
• Một vùng lưu trữ riêng được dùng bởi nhiều thư viện thời gian thực và thự viện liên kết động (DLLs).
Cấu trúc dữ liệu chủ yếu của luồng gồm:
• RTHREAD (executive thread block-khối luồng thực thi).
• KTHREAD (kernel thread-khối luồng nhân).
• TEB (thread environment block-khối môi trường luồng)
Các thành phần chủ yếu của RTHREAD gồm một con trỏ chỉ tới quá trình nào luồng thuộc về và địa chỉ của thủ tục mà luồng bắt đầu điều khiển trong đó.ETHREAD cũng chứa một con trỏ chỉ tới KTHREAD tương ứng.
• KTHREAD gồm thông tin định thời và đồng bộ hóa cho luồng. Ngoài ra,KTHREAD chứa ngăn xếp nhân (được dùng khi luồng đang chạy trong chế độ nhân)và con trỏ chỉ tới TEB.
• ETHREAD và KTHREAD tồn tại hoàn toàn ở không gian nhân; điều này có nghĩa chỉ nhân có thể truy xuất chúng.
• TEB là cấu trúc dữ liệu trong không gian người dùng được truy xuất khi luồng đang chạy ở chế độ người dùng. Giữa những trường khác nhau, TEB chứa ngăn xếp người dùng và một mảng cho dữ liệu đặc tả luồng (mà Windows gọi là lưu trữ cục bộ luồng)
NguyenDinhHop (I11C)- Tổng số bài gửi : 14
Join date : 26/08/2011
Re: Thảo luận Bài 5 (Đa luồng)
Những ích lợi của công nghệ đa luồng
+ Đảm bảo được khả năng đáp ứng của tiến trình tốt hơn, khi lập trình đa luồng thì một khi 1 luồng có sự cố thì luồng khác vẫn làm việc, vẫn phản hồi ,trong trường hợp lập trình đơn luồng khi gặp sự cố thì luồng đó sẽ chậm và làm chậm luôn cả tiến trình, đa luồng một ứng dụng giao tiếp cho phép một chương trình tiếp tục chạy thậm chí nếu một phần của nó bị khóa hay đang thực hiện một thao tác dài, do đó gai tăng sự đáp ứng đối với người dùng, Ví dụ : một trình duyệt web vẫn có thể đáp ứng người dùng bằng một luồng trong khi vẫn nạp bằng một luồng khác.
Ví dụ : Các cô ở tổng đài 108 là các luồng , khi khách hàng điện thoại hỏi 108, thì một trong các cô (người thứ nhất) sẽ trả lời, nếu trong thời điểm đó khách hàng thứ hai gọi 108,thì một trong các cô (cô thứ 2) còn lại sẽ trả lời
+ Theo mặc định các luồng có thể dùng chung bộ nhớ và tai nguyên của luồng cha. Thuận lợi của việc chia sẻ mã là nó cho phép một ứng dụng có nhiều hoạt động của các luồng khác nằm trong cùng không gian, địa chỉ,vài luồng cùng vận hành trong một vùng địa chỉ dễ dùng chung tài nguyên hơn so với trường hợp đa tiến trình.
Ví dụ : trong nhà có kệ sách, xe máy, máy vi tính … mọi người có thể dùng chung và sử dụng chung kệ sách, xe máy, máy vi tính. Trong khi không thể dùng chung những đồ dùng trên với nhà khác được
Trong lớp chúng ta có thể dùng bảng củ lớp mình, chúng ta có thể chia sẻ các thông tin cần thiết cho tất cả các thành viên ở trong lớp biết,trong khi chúng ta khong thể dùng chung bảng của lớp khác để chia sẻ thông tin cho lớp mình được.
+ Tiết kiệm (Economy) : Cấp phát bộ nhớ và tài nguyên cho tiến trình là công việc rất tốn kém. Do luồng có thể dùng chung tài nguyên với luồng cha và các luồng khác, việc tạo lập ngữ cảnh cũng nhanh hơn (Solaris2, tạo tiến trình chậm hơn 30 lần, chuyển ngữ cảnh chậm hơn 5 lần
Ví dụ : Các bạn trong lớp là các luồng đang dùng chung một cái bảng của lớp, ai cần ghi thì ghi, ai cần thì chụp hình về xem
Có thể bố trí một chỗ ngồi ở trong lớp cho một bạn đến sau dễ dàng hơn việc làm một chiếc ghế khác cho bạn đó.
+ Chuyển ngữ cảnh từ luồng này sang luồng khác thì nhanh hơn chuyển ngữ cảnh từ tiến trình này sang tiến trình khác.
+ Tận dụng được ưu thế kiến trúc đa xử lý (nhiều CPU). Khi đa luồng thì 1 luồng dùng CPU này và 1 luồng dùng CPU khác sẽ nhanh hơn và các luồng có thể làm việc song song , mỗi luồng có thể chạy bởi CPU riêng. Tiến trình đa luồng sẽ làm việc nhanh hơn tiến trình đơn luồng.
+ Lập trình đa luồng dễ dàng hơn lập trình đa tiến trình.
+ Đảm bảo được khả năng đáp ứng của tiến trình tốt hơn, khi lập trình đa luồng thì một khi 1 luồng có sự cố thì luồng khác vẫn làm việc, vẫn phản hồi ,trong trường hợp lập trình đơn luồng khi gặp sự cố thì luồng đó sẽ chậm và làm chậm luôn cả tiến trình, đa luồng một ứng dụng giao tiếp cho phép một chương trình tiếp tục chạy thậm chí nếu một phần của nó bị khóa hay đang thực hiện một thao tác dài, do đó gai tăng sự đáp ứng đối với người dùng, Ví dụ : một trình duyệt web vẫn có thể đáp ứng người dùng bằng một luồng trong khi vẫn nạp bằng một luồng khác.
Ví dụ : Các cô ở tổng đài 108 là các luồng , khi khách hàng điện thoại hỏi 108, thì một trong các cô (người thứ nhất) sẽ trả lời, nếu trong thời điểm đó khách hàng thứ hai gọi 108,thì một trong các cô (cô thứ 2) còn lại sẽ trả lời
+ Theo mặc định các luồng có thể dùng chung bộ nhớ và tai nguyên của luồng cha. Thuận lợi của việc chia sẻ mã là nó cho phép một ứng dụng có nhiều hoạt động của các luồng khác nằm trong cùng không gian, địa chỉ,vài luồng cùng vận hành trong một vùng địa chỉ dễ dùng chung tài nguyên hơn so với trường hợp đa tiến trình.
Ví dụ : trong nhà có kệ sách, xe máy, máy vi tính … mọi người có thể dùng chung và sử dụng chung kệ sách, xe máy, máy vi tính. Trong khi không thể dùng chung những đồ dùng trên với nhà khác được
Trong lớp chúng ta có thể dùng bảng củ lớp mình, chúng ta có thể chia sẻ các thông tin cần thiết cho tất cả các thành viên ở trong lớp biết,trong khi chúng ta khong thể dùng chung bảng của lớp khác để chia sẻ thông tin cho lớp mình được.
+ Tiết kiệm (Economy) : Cấp phát bộ nhớ và tài nguyên cho tiến trình là công việc rất tốn kém. Do luồng có thể dùng chung tài nguyên với luồng cha và các luồng khác, việc tạo lập ngữ cảnh cũng nhanh hơn (Solaris2, tạo tiến trình chậm hơn 30 lần, chuyển ngữ cảnh chậm hơn 5 lần
Ví dụ : Các bạn trong lớp là các luồng đang dùng chung một cái bảng của lớp, ai cần ghi thì ghi, ai cần thì chụp hình về xem
Có thể bố trí một chỗ ngồi ở trong lớp cho một bạn đến sau dễ dàng hơn việc làm một chiếc ghế khác cho bạn đó.
+ Chuyển ngữ cảnh từ luồng này sang luồng khác thì nhanh hơn chuyển ngữ cảnh từ tiến trình này sang tiến trình khác.
+ Tận dụng được ưu thế kiến trúc đa xử lý (nhiều CPU). Khi đa luồng thì 1 luồng dùng CPU này và 1 luồng dùng CPU khác sẽ nhanh hơn và các luồng có thể làm việc song song , mỗi luồng có thể chạy bởi CPU riêng. Tiến trình đa luồng sẽ làm việc nhanh hơn tiến trình đơn luồng.
+ Lập trình đa luồng dễ dàng hơn lập trình đa tiến trình.
NguyenTienPhong083 (I11C)- Tổng số bài gửi : 37
Join date : 26/08/2011
Age : 36
Re: Thảo luận Bài 5 (Đa luồng)
Tiến trình đơn luồng và tiến trình đa luồng
Tiến trình đơn luồng( Single - threaded) : là mỗi một luồng có 1 nội dung thanh ghi và ngăn xếp riêng nhưng mà dùng chung data và chung code
Tiến trình đa luồng (multithreaded) : là tiến trình với 1 luồng chính và 2 luồng phụ, mỗi luồng có nội dung các thanh ghi riêng, ngăn xếp riêng co các luồng đó và được dùng chung code,data và file. Mỗi luồng được điều khiển bởi Hệ diều hành.
Tiến trình đơn luồng( Single - threaded) : là mỗi một luồng có 1 nội dung thanh ghi và ngăn xếp riêng nhưng mà dùng chung data và chung code
Tiến trình đa luồng (multithreaded) : là tiến trình với 1 luồng chính và 2 luồng phụ, mỗi luồng có nội dung các thanh ghi riêng, ngăn xếp riêng co các luồng đó và được dùng chung code,data và file. Mỗi luồng được điều khiển bởi Hệ diều hành.
NguyenTienPhong083 (I11C)- Tổng số bài gửi : 37
Join date : 26/08/2011
Age : 36
Lập Trình Đa Luồng Với C#
C# 4.0 ra đời hỗ trợ mạnh mẽ lập trình đa luồng (multi thread programming). Phạm vi bài viết nhằm cung cấp một số khái niệm, class cơ bản hỗ trợ việc lập trình
1. Lớp Task:
Lớp Task đơn giản hóa đáng kể việc sử dụng CLR Thread pool, thậm chí còn có thể giúp gia tăng tốc độ. Đó là nhờ bản hiện thực của lớp Task đã tận dụng các kĩ thuật đồng bộ không cần khóa (lock-free) để giảm tối đa số khóa trong chương trình. Sử dụng lớp Task đơn giản như sau:
Task myTask = Task.Factory.StartNew(() => {
// do something here
});
Phương thức StartNew() nhận vào một delegate không có tham số và không trả trị (ví dụ trên dùng cú pháp của toán tử lambda). Delegate này sau đó sẽ được thực thi trong một luồng riêng. Ngoài ra lớp Task còn có một số phương thức như ContinueWith() để thực hiện nhiều tác vụ nối tiếp nhau. Trong trường hợp đó, đoạn code thường được đặt trong khối try…catch:
try
{
Task myTask = Task.Factory.StartNew(() => {
// do something here
myTask.ContinueWith(() => {
// …
}
});
}
catch (AggregateException ex)
{
// do something here
}
Trong trường hợp này, exception có thể phát sinh tại task thứ nhất hoặc task thứ hai (task trong câu lệnh ContinueWith). AggregateException là kiểu exception đặc biệt để bắt một tập hợp các exception có thể xảy ra từ bất cứ task nào.
2. Lớp Parallel:
Lớp Parallel cung cấp các phương thức static cho phép thực hiện một số tác vụ truyền thống theo kiểu song song. Hai phương thức phổ biến nhất là For() và ForEach(), có chức năng như một vòng lặp thông thường nhưng có thể phân hoạch collection thành nhiều phần để xử lý đồng thời. Ví dụ:
int[] numbers = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Parallel.For( 0, numbers.Length, (i) =>
{
numbers[i] = number[i] * 2;
Console.WriteLine(numbers[i]);
});
Lưu ý rằng kết quả xuất ra ở mỗi lần chạy có thể khác nhau và không giống với thứ tự ban đầu trong mảng, điều này chứng tỏ các thao tác được thực thi song song. Một điểm chú ý quan trọng khác là tốc độ. Việc thực thi song song không đồng nghĩa với việc gia tăng tốc độ, đặc biệt trong các trường hợp đơn giản như trên. Tốc độ thực thi phụ thuộc vào nhiều yếu tố khác nhau, và đa luồng sẽ hầu như không mang lại cải thiện tốc độ nào trên các hệ thống một bộ xử lý (các hệ thống đa nhân có thể coi như nhiều bộ xử lý). Mặc dù khả năng xử lý song song là rất hấp dẫn, chúng cần tránh bị lạm dụng.
3. Thread-safe collections:
Vấn đề đồng bộ hóa là một trong những vấn đề phức tạp nhất của lập trình đa luồng. Nhằm giảm bớt gánh nặng cho lập trình viên, .NET Framework 4 cung cấp sẵn các tập hợp an toàn luồng. Đây là các tập hợp được thiết kế để hỗ trợ việc truy vấn đồng thời từ nhiều luồng khác nhau. Ngoài việc đơn giản hóa đáng kể các thao tác với dữ liệu, các tập hợp này còn được tối ưu về mặt tốc độ với việc áp dụng các kĩ thuật đồng bộ lock-free. NET Framework 4 đi kèm theo các thread-safe collection sau: ConcurrentQueue, ConcurrentBag, ConcurrentStack, ConcurrentDictionary. Các tập hợp này có các phương thức cho phép thêm, xóa và lặp qua các phần tử trong môi trường đa luồng một cách an toàn và hiệu quả. Đây là các công cụ hữu ích mà lập trình viên nên tìm hiểu sử dụng để tiết kiệm thời gian và công sức.
1. Lớp Task:
Lớp Task đơn giản hóa đáng kể việc sử dụng CLR Thread pool, thậm chí còn có thể giúp gia tăng tốc độ. Đó là nhờ bản hiện thực của lớp Task đã tận dụng các kĩ thuật đồng bộ không cần khóa (lock-free) để giảm tối đa số khóa trong chương trình. Sử dụng lớp Task đơn giản như sau:
Task myTask = Task.Factory.StartNew(() => {
// do something here
});
Phương thức StartNew() nhận vào một delegate không có tham số và không trả trị (ví dụ trên dùng cú pháp của toán tử lambda). Delegate này sau đó sẽ được thực thi trong một luồng riêng. Ngoài ra lớp Task còn có một số phương thức như ContinueWith() để thực hiện nhiều tác vụ nối tiếp nhau. Trong trường hợp đó, đoạn code thường được đặt trong khối try…catch:
try
{
Task myTask = Task.Factory.StartNew(() => {
// do something here
myTask.ContinueWith(() => {
// …
}
});
}
catch (AggregateException ex)
{
// do something here
}
Trong trường hợp này, exception có thể phát sinh tại task thứ nhất hoặc task thứ hai (task trong câu lệnh ContinueWith). AggregateException là kiểu exception đặc biệt để bắt một tập hợp các exception có thể xảy ra từ bất cứ task nào.
2. Lớp Parallel:
Lớp Parallel cung cấp các phương thức static cho phép thực hiện một số tác vụ truyền thống theo kiểu song song. Hai phương thức phổ biến nhất là For() và ForEach(), có chức năng như một vòng lặp thông thường nhưng có thể phân hoạch collection thành nhiều phần để xử lý đồng thời. Ví dụ:
int[] numbers = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Parallel.For( 0, numbers.Length, (i) =>
{
numbers[i] = number[i] * 2;
Console.WriteLine(numbers[i]);
});
Lưu ý rằng kết quả xuất ra ở mỗi lần chạy có thể khác nhau và không giống với thứ tự ban đầu trong mảng, điều này chứng tỏ các thao tác được thực thi song song. Một điểm chú ý quan trọng khác là tốc độ. Việc thực thi song song không đồng nghĩa với việc gia tăng tốc độ, đặc biệt trong các trường hợp đơn giản như trên. Tốc độ thực thi phụ thuộc vào nhiều yếu tố khác nhau, và đa luồng sẽ hầu như không mang lại cải thiện tốc độ nào trên các hệ thống một bộ xử lý (các hệ thống đa nhân có thể coi như nhiều bộ xử lý). Mặc dù khả năng xử lý song song là rất hấp dẫn, chúng cần tránh bị lạm dụng.
3. Thread-safe collections:
Vấn đề đồng bộ hóa là một trong những vấn đề phức tạp nhất của lập trình đa luồng. Nhằm giảm bớt gánh nặng cho lập trình viên, .NET Framework 4 cung cấp sẵn các tập hợp an toàn luồng. Đây là các tập hợp được thiết kế để hỗ trợ việc truy vấn đồng thời từ nhiều luồng khác nhau. Ngoài việc đơn giản hóa đáng kể các thao tác với dữ liệu, các tập hợp này còn được tối ưu về mặt tốc độ với việc áp dụng các kĩ thuật đồng bộ lock-free. NET Framework 4 đi kèm theo các thread-safe collection sau: ConcurrentQueue, ConcurrentBag, ConcurrentStack, ConcurrentDictionary. Các tập hợp này có các phương thức cho phép thêm, xóa và lặp qua các phần tử trong môi trường đa luồng một cách an toàn và hiệu quả. Đây là các công cụ hữu ích mà lập trình viên nên tìm hiểu sử dụng để tiết kiệm thời gian và công sức.
AnhDuong- Tổng số bài gửi : 8
Join date : 30/08/2011
Ví dụ về lập trình đa luồng
Các bạn nào xem cho ý kiến nhé
Tạo 3 thread như sau:
Thread 1: đẩy vào queue 1 số tự nhiên lẻ trong khoảng 1, .., 10
Thread 2: đẩy vào queue 1 số tự nhiên chẵn trong khoảng 1, .., 10
Thread 3: Lấy trong queue ra 1 số tự nhiên ở đầu và in ra màn hình (in xong xóa số đó trong queue)
Code
#include <windows.h>
#include <queue>
#include <conio.h>
#include <stdio.h>
#include <tchar.h>
using namespace std;
typedef queue<int> queue_int;
unsigned long __stdcall Thread1(void* param);
unsigned long __stdcall Thread2(void* param);
unsigned long __stdcall Thread3(void* param);
void* handler_thread1 = 0;
void* handler_thread2 = 0;
void* handler_thread3 = 0;
int running1, running2;
void* mutex;
queue_int integer_queue;
unsigned int number = 0;
///////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
//HWND hwnd = GetConsoleWindow();
mutex = CreateMutex(0, false, 0);
unsigned long id_thread;
handler_thread1 = CreateThread(0, 0, Thread1, 0, 0, &id_thread);
if(!handler_thread1)
{
printf("Cannot create thread1. Error code = %d\n", GetLastError());
getch();
return -1;
}
handler_thread2 = CreateThread(0, 0, Thread2, 0, 0, &id_thread);
if(!handler_thread2)
{
printf("Cannot create thread2. Error code = %d\n", GetLastError());
running1 = 0;
WaitForSingleObject(handler_thread1, INFINITE);
getch();
return -1;
}
handler_thread3 = CreateThread(0, 0, Thread3, 0, 0, &id_thread);
if(!handler_thread3)
{
printf("Cannot create thread3. Error code = %d\n", GetLastError());
running1 = 0;
running2 = 0;
WaitForSingleObject(handler_thread2, INFINITE);
getch();
return -1;
}
WaitForSingleObject(handler_thread3, INFINITE);
printf("\nEnd Thread3\n");
CloseHandle(handler_thread1);
CloseHandle(handler_thread2);
CloseHandle(handler_thread3);
printf("\n\nExit program\n");
Sleep(1000);
return 0;
}
///////////////////////////////////////////////////////
unsigned long __stdcall Thread1(void* param)
{
running1 = 1;
while(running1)
{
WaitForSingleObject(mutex, INFINITE);
if(!(number % 2))
{
integer_queue.push(number++ % 10 + 1);
}
ReleaseMutex(mutex);
}
printf("\nEnd Thread1\n");
return 0;
}
///////////////////////////////////////////////////////
unsigned long __stdcall Thread2(void* param)
{
running2 = 1;
while(running2)
{
WaitForSingleObject(mutex, INFINITE);
if(number % 2)
{
integer_queue.push(number++ % 10 + 1);
}
ReleaseMutex(mutex);
}
WaitForSingleObject(handler_thread1, INFINITE);
printf("\nEnd Thread2\n");
return 0;
}
unsigned long __stdcall Thread3(void* param)
{
while(1)
{
WaitForSingleObject(mutex, INFINITE);
if(!integer_queue.empty())
{
int n = integer_queue.front();
printf("%4d", n);
if(n && n % 10 == 0)
printf("\n");
integer_queue.pop();
}
if(kbhit())
{
char key = getch();
switch(key)
{
case 'P':
case 'p':
{
while(1)
{
if(kbhit())
{
char key_in = getch();
if(key_in == 'C' || key_in == 'c' )
break;
else if(key_in == 0x1B)
{
running1 = 0;
running2 = 0;
ReleaseMutex(mutex);
WaitForSingleObject(handler_thread2, INFINITE);
return 0;
}
}
}
}
break;
case 0x1B:
{
running1 = 0;
running2 = 0;
ReleaseMutex(mutex);
WaitForSingleObject(handler_thread2, INFINITE);
}
return 0;
default:
break;
}
}
else
Sleep(1);
ReleaseMutex(mutex);
}
printf("\nEnd Thread3\n");
return 0;
}
Tạo 3 thread như sau:
Thread 1: đẩy vào queue 1 số tự nhiên lẻ trong khoảng 1, .., 10
Thread 2: đẩy vào queue 1 số tự nhiên chẵn trong khoảng 1, .., 10
Thread 3: Lấy trong queue ra 1 số tự nhiên ở đầu và in ra màn hình (in xong xóa số đó trong queue)
Code
#include <windows.h>
#include <queue>
#include <conio.h>
#include <stdio.h>
#include <tchar.h>
using namespace std;
typedef queue<int> queue_int;
unsigned long __stdcall Thread1(void* param);
unsigned long __stdcall Thread2(void* param);
unsigned long __stdcall Thread3(void* param);
void* handler_thread1 = 0;
void* handler_thread2 = 0;
void* handler_thread3 = 0;
int running1, running2;
void* mutex;
queue_int integer_queue;
unsigned int number = 0;
///////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
//HWND hwnd = GetConsoleWindow();
mutex = CreateMutex(0, false, 0);
unsigned long id_thread;
handler_thread1 = CreateThread(0, 0, Thread1, 0, 0, &id_thread);
if(!handler_thread1)
{
printf("Cannot create thread1. Error code = %d\n", GetLastError());
getch();
return -1;
}
handler_thread2 = CreateThread(0, 0, Thread2, 0, 0, &id_thread);
if(!handler_thread2)
{
printf("Cannot create thread2. Error code = %d\n", GetLastError());
running1 = 0;
WaitForSingleObject(handler_thread1, INFINITE);
getch();
return -1;
}
handler_thread3 = CreateThread(0, 0, Thread3, 0, 0, &id_thread);
if(!handler_thread3)
{
printf("Cannot create thread3. Error code = %d\n", GetLastError());
running1 = 0;
running2 = 0;
WaitForSingleObject(handler_thread2, INFINITE);
getch();
return -1;
}
WaitForSingleObject(handler_thread3, INFINITE);
printf("\nEnd Thread3\n");
CloseHandle(handler_thread1);
CloseHandle(handler_thread2);
CloseHandle(handler_thread3);
printf("\n\nExit program\n");
Sleep(1000);
return 0;
}
///////////////////////////////////////////////////////
unsigned long __stdcall Thread1(void* param)
{
running1 = 1;
while(running1)
{
WaitForSingleObject(mutex, INFINITE);
if(!(number % 2))
{
integer_queue.push(number++ % 10 + 1);
}
ReleaseMutex(mutex);
}
printf("\nEnd Thread1\n");
return 0;
}
///////////////////////////////////////////////////////
unsigned long __stdcall Thread2(void* param)
{
running2 = 1;
while(running2)
{
WaitForSingleObject(mutex, INFINITE);
if(number % 2)
{
integer_queue.push(number++ % 10 + 1);
}
ReleaseMutex(mutex);
}
WaitForSingleObject(handler_thread1, INFINITE);
printf("\nEnd Thread2\n");
return 0;
}
unsigned long __stdcall Thread3(void* param)
{
while(1)
{
WaitForSingleObject(mutex, INFINITE);
if(!integer_queue.empty())
{
int n = integer_queue.front();
printf("%4d", n);
if(n && n % 10 == 0)
printf("\n");
integer_queue.pop();
}
if(kbhit())
{
char key = getch();
switch(key)
{
case 'P':
case 'p':
{
while(1)
{
if(kbhit())
{
char key_in = getch();
if(key_in == 'C' || key_in == 'c' )
break;
else if(key_in == 0x1B)
{
running1 = 0;
running2 = 0;
ReleaseMutex(mutex);
WaitForSingleObject(handler_thread2, INFINITE);
return 0;
}
}
}
}
break;
case 0x1B:
{
running1 = 0;
running2 = 0;
ReleaseMutex(mutex);
WaitForSingleObject(handler_thread2, INFINITE);
}
return 0;
default:
break;
}
}
else
Sleep(1);
ReleaseMutex(mutex);
}
printf("\nEnd Thread3\n");
return 0;
}
AnhDuong- Tổng số bài gửi : 8
Join date : 30/08/2011
so sánh sự khác nhau giữa lập trình đa luồng và đa tiến trình
Bài sau đây đã dược post trên trang của thầy và được thầy xem qua, mình đem về để chúng ta cùng tham khảo nhé/
Giống nhau :
1. Đều có thông tin trạng thái
2. Luồng còn được gọi là tiến trình nhẹ
3. Nhiều luồng or nhiều tiến trình có thể liên quan đến một chương trình
4. Chia sẻ tài nguyên cho nhau
5. Tăng tốc tính toán
6. Đảm bảo tính đơn thể
Khác nhau
1. Do luồng cùng vận hành trong 1 vùng địa chỉ vì vậy dể dùng chung tài nguyên hơn đa tiến trình
VD : Mượn đồ dùng trong gia đình thì dể hơn mượn của hàng xóm
2. Do luồng chung tài nguyên với cha & các luồng khác nên việc tạo lập & chuyển ngữ cảnh cũng
nhanh hơn tiến trình
VD : Việc ngăn riêng ra một phòng trong nhà thì nhanh hơn là chờ nhà nước cấp cho
một căn hộ
3. Cấp phát bộ nhớ & tài nguyên cho tiến trình thì tốn kém hơn luồng
4. Lập trình đa luồng thì dể hơn đa tiến trình
Giống nhau :
1. Đều có thông tin trạng thái
2. Luồng còn được gọi là tiến trình nhẹ
3. Nhiều luồng or nhiều tiến trình có thể liên quan đến một chương trình
4. Chia sẻ tài nguyên cho nhau
5. Tăng tốc tính toán
6. Đảm bảo tính đơn thể
Khác nhau
1. Do luồng cùng vận hành trong 1 vùng địa chỉ vì vậy dể dùng chung tài nguyên hơn đa tiến trình
VD : Mượn đồ dùng trong gia đình thì dể hơn mượn của hàng xóm
2. Do luồng chung tài nguyên với cha & các luồng khác nên việc tạo lập & chuyển ngữ cảnh cũng
nhanh hơn tiến trình
VD : Việc ngăn riêng ra một phòng trong nhà thì nhanh hơn là chờ nhà nước cấp cho
một căn hộ
3. Cấp phát bộ nhớ & tài nguyên cho tiến trình thì tốn kém hơn luồng
4. Lập trình đa luồng thì dể hơn đa tiến trình
AnhDuong- Tổng số bài gửi : 8
Join date : 30/08/2011
Re: Thảo luận Bài 5 (Đa luồng)
Tranvancanh(I11C) đã viết:Hôm qua trong lớp Thầy có hỏi 1 câu trong code của chương trình có 2 hàm là:buithithudung24 (i11c) đã viết:Hàm GetCurrentThread: dùng để lấy về mục quản của luồng sản xuất hiện hành(mục quản: là con số do hệ điều hành cấp ho luồng hiện hành)
Hàm SuspendThread: dùng để tạm ngưng công việc của hàm với mục quản cho trước
Hàm Sleep: dùng để ngủ 1 số miligiay cho trước,hết khoảng thời gian đó nhà tiêu thụ lại làm việc tiếp
Hàm GetTickCount(): dùng để lấy số miligiay trôi qua kể từ khi hệ điều hành khởi động cho đến thời điểm gọi hàm này
HÀm ResumeThread: dùng để tiếp tục công việc của luồng với mục quản cho trước
Hàm CloseHandle: dùng để hủy đối tượng cho trước với mục quản cho trước. vd: CLoseHandle (45) :luồng 45 không làm việc nữa,bị đóng lại
Sleep(1);
ShowBuffer();
Vậy 2 hàm trên nếu bỏ đi hàm Sleep có ảnh hưởng gì không và tại sao phải dùng hàm sleep bỏ nó đi có được không? Nếu bỏ nó đi thì hàm chạy sẽ sai, sai là do showbuffer ngày mà không ngủ trước.
1 Vd minh họa: Một người chụp hình và có 2 người đứng chờ bấm máy nếu người chụp hình chụp ngay không chờ 2 người kia hay có 1 người nữa cũng mún chụp ảnh mà chưa vào kịp thì bức ảnh sẽ bị lỡ, xấu đi. Phải chờ chuẩn bị xong hoàn toàn thì bức ảnh chụp nó mới hoàn hảo, đẹp. Nên phải có hàm Sleep để tiến trình chuẩn bị hoàn tất rồi mới thực thi mới show lên.
Hiii mình nhớ Thấy giảng như thế. thanks các bạn đã theo dõi.
vậy thì thời gian chờ để tiến trình chuẩn bị để hoàn tất là bao nhiêu???? Thầy có nói là sang bài sau sẽ giảng tới phần này nhưng mà bạn (hoặc các bạn) có thể giải thích trước cho mình rõ có được không? mình cũng đang còn gà mờ phần này lắm!!!
Thanks
XuanThai_I11C- Tổng số bài gửi : 20
Join date : 10/09/2011
Age : 38
CPU đa lõi : Hướng tới tương lai
Trong ngành công nghiệp máy tính thì đây là một bước tiến quan trọng. Trong vòng vài năm tới bạn sẽ được tiếp xúc một tương lai mạng với các máy tính đa lõi. Điều này sẽ ảnh hưởng tới mạng của bạn, từ việc đăng ký và giá cả phát triển phần mềm tới toàn bộ trung tâm cấu trúc mạng.
Bài viết này sẽ giải thích rõ tại sao ngành công nghiệp lại chuyển biến theo hướng này và sẽ đưa ra một vài ảnh hưởng của nó đối với bạn cũng như mạng của bạn.
Thuật ngữ
Thuật ngữ trong ngành công nghiệp CNTT có thể khiến cho bạn bối rối. Vì vậy trước tiên ta phải hiểu rõ vấn đề đang nói đến. CPU đa lõi là có chứa từ hai bộ xử lý trở lên trong một vi mạch. Điều này hoàn toàn khác so với thuật ngữ “đa chíp” - là có chứa nhiều vi mạch được đóng gói cùng nhau. Và cũng hoàn toàn khác so với thuật ngữ “đa CPU” - là có nhiều bộ xử lý làm việc cùng nhau.
Ưu điểm
Vậy tại sao các kiến trúc sư phần cứng lại muốn đặt nhiều CPU vào cùng một chip? Lý do lớn nhất là việc đặt nhiều lõi lên cùng một vi mạch sẽ giúp giảm không gian trên bản mạch chính khi có nhu cầu muốn sử dụng với số lượng CPU lõi đơn tương đương. Thêm nữa, lợi thế của việc sử dụng đa lõi trên cùng một vi mạch đương nhiên sẽ làm việc kết hợp cùng nhau chặt chẽ và nâng cao được hiệu quả hơn.
Khả năng tiết kiệm năng lượng cũng được phát huy thấy rõ đối với thiết kế này. Khi nhiều lõi cùng nằm trên một chip, xung tín hiệu truyền giữa các lõi sẽ ngắn hơn. Ngoài ra, đặc trưng của CPU đa lõi là chạy với điện năng thấp hơn vì công suất tiêu tốn để tín hiệu truyền trên dây bằng với bình phương điện áp chia cho điện trở trong dây, do đó điện năng thấp hơn sẽ dẫn đến kết quả là nguồn điện sử dụng đi.
Một lý do khác đối với việc tiết kiệm nguồn điện là tốc độ đồng hồ. Như bạn thấy, CPU đa lõi có thể thực thi các hoạt động nhiều lần hơn trong một giây trong khi tần số thấp hơn. Ví dụ bộ xử lý MIT RAW 16 lõi hoạt động ở tần số 425MHz có thể thực thi gấp 100 lần các hoạt động trong một giây đối với Intel Pentium 3 đang chạy ở tần số 600 MHz. Vậy tần số như vậy ảnh hưởng như thế nào với sự tiêu thụ điện năng của CPU? Đây quả là vấn đề khá phức tạp, nhưng bạn phải hiểu một quy tắc đơn giản là mỗi một phần trăm tăng thêm tốc độ đồng hồ sẽ tăng 3% điện năng tiêu thụ. Và tất nhiên là điều đó còn chưa tính tới tác động của các nhân tố khác có ảnh hưởng tới sự tiêu thụ điện năng.
CPU đa lõi còn có thể chia sẻ một mạch ghép nối bus tốt như mạch lưu trữ. Theo Intel, CPU Core 2 dual có thể lên tới 4MB được chia sẻ L2 Cache.
Nói về cache CPU, sản phẩm Tile64 (một bộ xử lý 64 bit) mới ra mắt gần đây của Tilera chính là một cache điển hình. Tile64 sử dụng một câu trúc lưới. Cấu trúc này cho phép các lõi riêng lẻ thực hiện các hoạt động khá khác nhau. Khi lõi hướng tới L2 cache và không tìm thấy cái cần tìm, nó đầu tiên sẽ tìm kiếm trong L2 cache của các lõi khác trên lưới trước khi yêu cầu dữ liệu từ bộ nhớ chính. Về cơ bản thì điều này có nghĩa là các hoạt động lưới giống như một L3 cache.
Tính năng lưu trữ đặc biệt của Tile64 là một điển hình của việc thay đổi chủ yếu trong cấu trúc máy tính. Các máy tính hiện nay đều tập trung vào bộ nhớ chính, và dùng bộ xử lý để truy cập tới bộ nhớ này. Điều này yêu cầu khá nhiều đến sự truyền thông và thường xảy ra vấn đề nghẽn hoặc giới hạn tốc độ xử lý. Với việc sử dụng đa lõi, ngành công nghiệp máy tính đã hướng tới một cấu trúc trung tâm truyền thông và xử lý tốt hơn. Cấu trúc mới này vừa đạt hiệu quả nhanh hơn và còn năng suất cao hơn trong việc sử dụng.
Cấu trúc bộ nhớ trung tâm hiện tại sẽ không thể thực hiện được hết các lợi thế của lõi đa nhân. Ví dụ, một bộ đọc lưu trữ điển hình chỉ cần 10% năng lượng cần thiết để đọc một off-chip nhớ xác định. Tốc độ hoạt động đọc off-chip sẽ bị giới hạn bởi công nghệ nhớ và phương tiện kết nối được sử dụng.
Bộ xử lý đa lõi sẽ trở nên phổ biến hơn và được sử dụng nhiều hơn. Khi đó, các chuyên gia phát triển phần mềm sẽ bắt đầu phát triển các ứng dụng đa tuyến thực sự và khi đó bạn sẽ thấy sự thay đổi trong các mạng. Mạng của bạn sẽ có khẳ năng thay đổi từ trung tâm bộ nhớ sang trung tâm truyền thông và xử lý. Mạng lúc đó tất nhiên sẽ không phù hợp để sử dụng bộ xử lý lõi kép hay lõi tứ (ngoại trừ máy tính sử dụng thông thường). Trang thiết bị mạng của bạn lúc đó có thể sẽ cần 10 hay cả trăm lõi.
Đa luồng
Nhưng kiến trúc này có tác dụng gì với các nhà phát triển phần mềm? Một nhân tố khác giới hạn lợi ích thực thi của CPU đa lõi là phần mềm chạy trên nó. Đối với người dùng bình thường, hiệu suất lớn nhất mà họ đạt được khi lựa chọn một CPU đa lõi là tính đa nhiệm được cải thiện. Ví dụ, với một CPU đa lõi bạn sẽ thấy sự cải thiện lớn khi xem DVD trong lúc máy vẫn đang được quét virus mà tốc độ không bị ảnh hưởng, bởi vì từng ứng dụng sẽ được gán trên các lõi khác nhau.
Nếu người dùng đang chạy một ứng dụng đơn trên máy tính đa lõi thì sẽ không thấy rõ được việc tăng hiệu suất đáng kể lắm. Bởi hầu hết các ứng dụng không được xử lý đa luồng. Chính vì vậy các ứng dụng cũng cần phải thay đổi trong thiết kế. Ví dụ một chương trình quét virus chạy trên một tuyến mới trong khi GUI lại chạy trên một tuyến khác. Việc xử lý đa luồng đúng cách là khi khối lượng công việc được phân chia thành nhiều luồng khác nhau. Việc quét virus là một ví dụ, luồng GUI làm việc rất ít, trong khi luồng quét virus thực hiện một nhiệm vụ rất nặng và không có khả năng chia nhỏ ra và gửi đến các lõi khác.
Việc phát triển một ứng dụng đa luồng đích thực yêu cầu rất nhiều công việc phức tạp. Điều này rõ ràng cũng tốn khá nhiều chi phí vào một chu trình thiết kế phần mềm. Đó là lý do tại sao phần lớn các ứng dụng phần mềm sẽ không được phát triển như các ứng dụng thực sự đa luồng cho đến khi số lượng lõi đủ cao để thực hiện nhiều tác vụ mà không làm ảnh hưởng tới hiệu suất. Và điều này sẽ đạt được khi người dùng có nhu cầu.
Tuy vậy các mạng của bạn còn có nhiều vấn đề khác. Các router có thể trở thành các thiết bị được chấp nhận rộng rãi trước tiên với kiến trúc đa lõi cũng như việc xử lý đa luồng. Các máy chủ cũng sẽ tăng hiệu suất đáng kể từ công nghệ mới này. Trong số các bạn có ai cho rằng vẫn chưa có các sản phẩm đa lõi? Điều này hoàn toàn có thể được cũng như điều tôi đã nói về bước tiến quan trọng đối với tầm quan trọng của lõi. Intel đã hứa rằng sẽ cung cấp một lõi 80 vào năm 2011 và điều này thực sự là rất đáng trông chờ.
Bài viết này sẽ giải thích rõ tại sao ngành công nghiệp lại chuyển biến theo hướng này và sẽ đưa ra một vài ảnh hưởng của nó đối với bạn cũng như mạng của bạn.
Thuật ngữ
Thuật ngữ trong ngành công nghiệp CNTT có thể khiến cho bạn bối rối. Vì vậy trước tiên ta phải hiểu rõ vấn đề đang nói đến. CPU đa lõi là có chứa từ hai bộ xử lý trở lên trong một vi mạch. Điều này hoàn toàn khác so với thuật ngữ “đa chíp” - là có chứa nhiều vi mạch được đóng gói cùng nhau. Và cũng hoàn toàn khác so với thuật ngữ “đa CPU” - là có nhiều bộ xử lý làm việc cùng nhau.
Ưu điểm
Vậy tại sao các kiến trúc sư phần cứng lại muốn đặt nhiều CPU vào cùng một chip? Lý do lớn nhất là việc đặt nhiều lõi lên cùng một vi mạch sẽ giúp giảm không gian trên bản mạch chính khi có nhu cầu muốn sử dụng với số lượng CPU lõi đơn tương đương. Thêm nữa, lợi thế của việc sử dụng đa lõi trên cùng một vi mạch đương nhiên sẽ làm việc kết hợp cùng nhau chặt chẽ và nâng cao được hiệu quả hơn.
Khả năng tiết kiệm năng lượng cũng được phát huy thấy rõ đối với thiết kế này. Khi nhiều lõi cùng nằm trên một chip, xung tín hiệu truyền giữa các lõi sẽ ngắn hơn. Ngoài ra, đặc trưng của CPU đa lõi là chạy với điện năng thấp hơn vì công suất tiêu tốn để tín hiệu truyền trên dây bằng với bình phương điện áp chia cho điện trở trong dây, do đó điện năng thấp hơn sẽ dẫn đến kết quả là nguồn điện sử dụng đi.
Một lý do khác đối với việc tiết kiệm nguồn điện là tốc độ đồng hồ. Như bạn thấy, CPU đa lõi có thể thực thi các hoạt động nhiều lần hơn trong một giây trong khi tần số thấp hơn. Ví dụ bộ xử lý MIT RAW 16 lõi hoạt động ở tần số 425MHz có thể thực thi gấp 100 lần các hoạt động trong một giây đối với Intel Pentium 3 đang chạy ở tần số 600 MHz. Vậy tần số như vậy ảnh hưởng như thế nào với sự tiêu thụ điện năng của CPU? Đây quả là vấn đề khá phức tạp, nhưng bạn phải hiểu một quy tắc đơn giản là mỗi một phần trăm tăng thêm tốc độ đồng hồ sẽ tăng 3% điện năng tiêu thụ. Và tất nhiên là điều đó còn chưa tính tới tác động của các nhân tố khác có ảnh hưởng tới sự tiêu thụ điện năng.
CPU đa lõi còn có thể chia sẻ một mạch ghép nối bus tốt như mạch lưu trữ. Theo Intel, CPU Core 2 dual có thể lên tới 4MB được chia sẻ L2 Cache.
Nói về cache CPU, sản phẩm Tile64 (một bộ xử lý 64 bit) mới ra mắt gần đây của Tilera chính là một cache điển hình. Tile64 sử dụng một câu trúc lưới. Cấu trúc này cho phép các lõi riêng lẻ thực hiện các hoạt động khá khác nhau. Khi lõi hướng tới L2 cache và không tìm thấy cái cần tìm, nó đầu tiên sẽ tìm kiếm trong L2 cache của các lõi khác trên lưới trước khi yêu cầu dữ liệu từ bộ nhớ chính. Về cơ bản thì điều này có nghĩa là các hoạt động lưới giống như một L3 cache.
Tính năng lưu trữ đặc biệt của Tile64 là một điển hình của việc thay đổi chủ yếu trong cấu trúc máy tính. Các máy tính hiện nay đều tập trung vào bộ nhớ chính, và dùng bộ xử lý để truy cập tới bộ nhớ này. Điều này yêu cầu khá nhiều đến sự truyền thông và thường xảy ra vấn đề nghẽn hoặc giới hạn tốc độ xử lý. Với việc sử dụng đa lõi, ngành công nghiệp máy tính đã hướng tới một cấu trúc trung tâm truyền thông và xử lý tốt hơn. Cấu trúc mới này vừa đạt hiệu quả nhanh hơn và còn năng suất cao hơn trong việc sử dụng.
Cấu trúc bộ nhớ trung tâm hiện tại sẽ không thể thực hiện được hết các lợi thế của lõi đa nhân. Ví dụ, một bộ đọc lưu trữ điển hình chỉ cần 10% năng lượng cần thiết để đọc một off-chip nhớ xác định. Tốc độ hoạt động đọc off-chip sẽ bị giới hạn bởi công nghệ nhớ và phương tiện kết nối được sử dụng.
Bộ xử lý đa lõi sẽ trở nên phổ biến hơn và được sử dụng nhiều hơn. Khi đó, các chuyên gia phát triển phần mềm sẽ bắt đầu phát triển các ứng dụng đa tuyến thực sự và khi đó bạn sẽ thấy sự thay đổi trong các mạng. Mạng của bạn sẽ có khẳ năng thay đổi từ trung tâm bộ nhớ sang trung tâm truyền thông và xử lý. Mạng lúc đó tất nhiên sẽ không phù hợp để sử dụng bộ xử lý lõi kép hay lõi tứ (ngoại trừ máy tính sử dụng thông thường). Trang thiết bị mạng của bạn lúc đó có thể sẽ cần 10 hay cả trăm lõi.
Đa luồng
Nhưng kiến trúc này có tác dụng gì với các nhà phát triển phần mềm? Một nhân tố khác giới hạn lợi ích thực thi của CPU đa lõi là phần mềm chạy trên nó. Đối với người dùng bình thường, hiệu suất lớn nhất mà họ đạt được khi lựa chọn một CPU đa lõi là tính đa nhiệm được cải thiện. Ví dụ, với một CPU đa lõi bạn sẽ thấy sự cải thiện lớn khi xem DVD trong lúc máy vẫn đang được quét virus mà tốc độ không bị ảnh hưởng, bởi vì từng ứng dụng sẽ được gán trên các lõi khác nhau.
Nếu người dùng đang chạy một ứng dụng đơn trên máy tính đa lõi thì sẽ không thấy rõ được việc tăng hiệu suất đáng kể lắm. Bởi hầu hết các ứng dụng không được xử lý đa luồng. Chính vì vậy các ứng dụng cũng cần phải thay đổi trong thiết kế. Ví dụ một chương trình quét virus chạy trên một tuyến mới trong khi GUI lại chạy trên một tuyến khác. Việc xử lý đa luồng đúng cách là khi khối lượng công việc được phân chia thành nhiều luồng khác nhau. Việc quét virus là một ví dụ, luồng GUI làm việc rất ít, trong khi luồng quét virus thực hiện một nhiệm vụ rất nặng và không có khả năng chia nhỏ ra và gửi đến các lõi khác.
Việc phát triển một ứng dụng đa luồng đích thực yêu cầu rất nhiều công việc phức tạp. Điều này rõ ràng cũng tốn khá nhiều chi phí vào một chu trình thiết kế phần mềm. Đó là lý do tại sao phần lớn các ứng dụng phần mềm sẽ không được phát triển như các ứng dụng thực sự đa luồng cho đến khi số lượng lõi đủ cao để thực hiện nhiều tác vụ mà không làm ảnh hưởng tới hiệu suất. Và điều này sẽ đạt được khi người dùng có nhu cầu.
Tuy vậy các mạng của bạn còn có nhiều vấn đề khác. Các router có thể trở thành các thiết bị được chấp nhận rộng rãi trước tiên với kiến trúc đa lõi cũng như việc xử lý đa luồng. Các máy chủ cũng sẽ tăng hiệu suất đáng kể từ công nghệ mới này. Trong số các bạn có ai cho rằng vẫn chưa có các sản phẩm đa lõi? Điều này hoàn toàn có thể được cũng như điều tôi đã nói về bước tiến quan trọng đối với tầm quan trọng của lõi. Intel đã hứa rằng sẽ cung cấp một lõi 80 vào năm 2011 và điều này thực sự là rất đáng trông chờ.
TranHuynhDucHanh(I11C)- Tổng số bài gửi : 6
Join date : 28/08/2011
Ví dụ nhỏ về đa luồng
Ví dụ này mình sẽ mô tả 2 luồng (cho đơn giản) được thực thi cùng một lúc.
Ở đây thì bạn cứ tưởng tượng ra rằng có hai thằng tên là A và B thi đếm từ 0 cho đến 100, thằng nào đếm xong trước thì báo cáo và được về chỗ. Tương ứng mình sẽ tạo ra 2 phương thức A() và B() (mỗi luồng sẽ xử lý một thằng).
void A()
{
for(int i=0; i<=100; i++)
{
Console.WriteLine(i.ToString());
}
Console.WriteLine("A đã đọc xong"); // Báo cáo đã đọc xong
}
void B()
{
for(int i=0; i<=100; i++)
{
Console.WriteLine(i.ToString());
}
Console.WriteLine("B đã đọc xong"); // Báo cáo đã đọc xong
}
Bây giờ thầy giáo (hoặc là bạn) bỗng cao hứng gọi 2 thằng lên thi đọc --> 2 thằng A và B cùng đọc. Đến đây trong phương thức hàm main() của chương trình bạn sẽ phải gọi 2 thằng này.
static void main()
{
ThreadStart ts1 = new ThreadStart(A); // Chỉ định thằng A lên đọc
ThreadStart ts2 = new ThreadStart(B); // Chỉ định thằng B lên đọc
// Sẵn sàng cho cuộc đấu (thi đếm nhanh )
Thread tA = new Thread(ts1);
Thread tB = new Thread(ts2);
// Bắt đầu bấm giờ
tA.Start();
tB.Start();
tA.Join();
tB.Join();
// Hai thằng tranh nhau đếm
Console.WriteLine("Cuộc thi kết thúc"); // Chờ đến khi 2 thằng đọc xong, không biết thằng nào sẽ thắng
Console.ReadLine();
}
Ở đây thì bạn cứ tưởng tượng ra rằng có hai thằng tên là A và B thi đếm từ 0 cho đến 100, thằng nào đếm xong trước thì báo cáo và được về chỗ. Tương ứng mình sẽ tạo ra 2 phương thức A() và B() (mỗi luồng sẽ xử lý một thằng).
void A()
{
for(int i=0; i<=100; i++)
{
Console.WriteLine(i.ToString());
}
Console.WriteLine("A đã đọc xong"); // Báo cáo đã đọc xong
}
void B()
{
for(int i=0; i<=100; i++)
{
Console.WriteLine(i.ToString());
}
Console.WriteLine("B đã đọc xong"); // Báo cáo đã đọc xong
}
Bây giờ thầy giáo (hoặc là bạn) bỗng cao hứng gọi 2 thằng lên thi đọc --> 2 thằng A và B cùng đọc. Đến đây trong phương thức hàm main() của chương trình bạn sẽ phải gọi 2 thằng này.
static void main()
{
ThreadStart ts1 = new ThreadStart(A); // Chỉ định thằng A lên đọc
ThreadStart ts2 = new ThreadStart(B); // Chỉ định thằng B lên đọc
// Sẵn sàng cho cuộc đấu (thi đếm nhanh )
Thread tA = new Thread(ts1);
Thread tB = new Thread(ts2);
// Bắt đầu bấm giờ
tA.Start();
tB.Start();
tA.Join();
tB.Join();
// Hai thằng tranh nhau đếm
Console.WriteLine("Cuộc thi kết thúc"); // Chờ đến khi 2 thằng đọc xong, không biết thằng nào sẽ thắng
Console.ReadLine();
}
TranHuynhDucHanh(I11C)- Tổng số bài gửi : 6
Join date : 28/08/2011
Re: Thảo luận Bài 5 (Đa luồng)
Chào bạn VoMinhHoang (I11C)!VoMinhHoang (I11C) đã viết:Đa luồng dùng chung các tiến trình trong hệ thống, quản trị công việc bên trong cấp phát giữa các tiến trình. (vd: tài nguyên dùng chung là bảng lớp học)
Tiến trình truyền thống dùng chung các tiến trình bên ngoài. Lập trình đa luồng dễ hơn lập trình đa tiến trình (như tạo mới luồng, chia sẻ, điều khiển dễ hơn..)
Giống nhau:
Đều có thông tin trạng thái
Luồng còn được gọi là tiến trình nhẹ
Nhiều luồng hoặc nhiều tiến trình có thể liên quan đến một chu trình
Chia sẻ tài nguyên cho nhau, tăng tốc tính toán, đảm bảo tính đơn thể
Khác nhau:
Do luồng cùng vận hành trong 1 vùng địa chỉ, vì vậy dễ dùng chung tài nguyên hơn đa tiến trình ví dụ mượn đồ trong gia đình dễ mượn đồ hơn của hàng xóm
Do luồng chung tài nguyên với luồng cha nên việc tạo lập và chuyển đổi ngữ cảnh cũng nhanh hơn tiến trình
Ví dụ: việc ngăn riêng ra một phòng trong nhà thì dễ hơn được nhà nước cấp cho một căn hộ
Cấp phát tài nguyên cho bộ nhớ thì tốn kém
Có một vấn đề mình không hiểu trong phần so sánh khác nhau giữa tiến trình và luồng. Bạn giải thích giúp nhé!
Mình không hiểu luồng cha đây là luồng gì?
-Theo như Thầy giảng trên lớp: Trong 1 tiến trình có thể có nhiều tiến trình con nhưng trong 1 luồng thì không có luồng con. Vậy lấy đâu ra luồng cha? Mình thấy trong các bài viết của các bạn khác cũng thế. Mình không biết cái nào mới đúng.
Rất mong các bạn góp ý giúp!!!
NguyThiGai (I11C)- Tổng số bài gửi : 28
Join date : 26/08/2011
Age : 37
Mô hình đa luồng
Nhiều hệ thống cung cấp sự hỗ trợ cả hai luồng nhân và luồng người dùng nên tạo ra nhiều mô hình đa luồng khác nhau. Chúng ta sẽ xem xét ba loại cài đặt luồng thông thường:
Mô hình nhiều-một:
Mô hình nhiều-một ánh xạ nhiều luồng cấp người dùng tới một luồng cấp nhân. Quản lý luồng được thực hiện trong không gian người dùng vì thế nó hiệu quả nhưng toàn bộ quá trình sẽ bị khóa nếu một luồng thực hiện lời gọi hệ thống khóa. Vì chỉ một luồng có thể truy xuất nhân tại một thời điểm nên nhiều luồng
không thể chạy song song trên nhiều bộ xử lý. Green threads-một thư viện luồng được cài đặt trên các hệ điều hành không hỗ trợ luồng nhân dùng mô hình nhiều-một.
Mô hình một-một:
Mô hình một-một ánh xạ mỗi luồng người dùng tới một luồng nhân. Nó cung cấp khả năng đồng hành tốt hơn mô hình nhiều-một bằng cách cho một luồng khác chạy khi một luồng thực hiện lời gọi hệ thống nghẽn; nó cũng cho phép nhiều luồng chạy song song trên các bộ xử lý khác nhau. Chỉ có một trở ngại trong mô hình này là tạo luồng người dùng yêu cầu tạo một luồng nhân tương ứng. Vì chi phí cho việc tạo luồng nhân có thể đè nặng lên năng lực thực hiện của ứng dụng, các cài đặt cho mô hình này giới hạn số luồng được hỗ trợ bởi hệ thống. Windows NT, Windows 2000 và OS/2 cài đặt mô hình một-một này.
Mô hình nhiều-nhiều:
Mô hình nhiều-nhiều đa hợp nhiều luồng cấp người dùng tới số lượng nhỏ hơn hay bằng các luồng nhân. Số lượng các luồng nhân có thể được xác định hoặc một ứng dụng cụ thể hay một máy cụ thể (một ứng dụng có thể được cấp nhiều luồng nhân trên một bộ đa xử lý hơn trên một bộ đơn xử lý). Trong khi mô hình nhiều-một cho phép người phát triển tạo nhiều luồng người dùng như họ muốn, thì đồng hành thật sự là không đạt được vì nhân có thể lập thời biểu chỉ một luồng tại một thời điểm. Mô hình một-một cho phép đồng hành tốt hơn nhưng người phát triển phải cẩn thận không tạo ra quá nhiều luồng trong một ứng dụng. Mô hình nhiều-nhiều gặp phải một trong hai vấn đề khiếm khuyết: người phát triển có thể tạo nhiều luồng người dùng khi cần thiết và các luồng nhân tương ứng có thể chạy song song trên một bộ đa xử lý. Khi một luồng thực hiện một lời gọi hệ thống khóa, nhân có thể lập thời biểu một luồng khác thực thi. Solaris 2, IRIX, HP-UX, và Tru64 UNIX hỗ trợ mô hình này.
Mô hình nhiều-một:
Mô hình nhiều-một ánh xạ nhiều luồng cấp người dùng tới một luồng cấp nhân. Quản lý luồng được thực hiện trong không gian người dùng vì thế nó hiệu quả nhưng toàn bộ quá trình sẽ bị khóa nếu một luồng thực hiện lời gọi hệ thống khóa. Vì chỉ một luồng có thể truy xuất nhân tại một thời điểm nên nhiều luồng
không thể chạy song song trên nhiều bộ xử lý. Green threads-một thư viện luồng được cài đặt trên các hệ điều hành không hỗ trợ luồng nhân dùng mô hình nhiều-một.
Mô hình một-một:
Mô hình một-một ánh xạ mỗi luồng người dùng tới một luồng nhân. Nó cung cấp khả năng đồng hành tốt hơn mô hình nhiều-một bằng cách cho một luồng khác chạy khi một luồng thực hiện lời gọi hệ thống nghẽn; nó cũng cho phép nhiều luồng chạy song song trên các bộ xử lý khác nhau. Chỉ có một trở ngại trong mô hình này là tạo luồng người dùng yêu cầu tạo một luồng nhân tương ứng. Vì chi phí cho việc tạo luồng nhân có thể đè nặng lên năng lực thực hiện của ứng dụng, các cài đặt cho mô hình này giới hạn số luồng được hỗ trợ bởi hệ thống. Windows NT, Windows 2000 và OS/2 cài đặt mô hình một-một này.
Mô hình nhiều-nhiều:
Mô hình nhiều-nhiều đa hợp nhiều luồng cấp người dùng tới số lượng nhỏ hơn hay bằng các luồng nhân. Số lượng các luồng nhân có thể được xác định hoặc một ứng dụng cụ thể hay một máy cụ thể (một ứng dụng có thể được cấp nhiều luồng nhân trên một bộ đa xử lý hơn trên một bộ đơn xử lý). Trong khi mô hình nhiều-một cho phép người phát triển tạo nhiều luồng người dùng như họ muốn, thì đồng hành thật sự là không đạt được vì nhân có thể lập thời biểu chỉ một luồng tại một thời điểm. Mô hình một-một cho phép đồng hành tốt hơn nhưng người phát triển phải cẩn thận không tạo ra quá nhiều luồng trong một ứng dụng. Mô hình nhiều-nhiều gặp phải một trong hai vấn đề khiếm khuyết: người phát triển có thể tạo nhiều luồng người dùng khi cần thiết và các luồng nhân tương ứng có thể chạy song song trên một bộ đa xử lý. Khi một luồng thực hiện một lời gọi hệ thống khóa, nhân có thể lập thời biểu một luồng khác thực thi. Solaris 2, IRIX, HP-UX, và Tru64 UNIX hỗ trợ mô hình này.
DuongTrungTinh(I11C)- Tổng số bài gửi : 31
Join date : 26/08/2011
Những lợi ích của lập trình đa luồng
Được chia làm 4 loại như sau:
1.Sự đáp ứng: đa luồng một ứng dụng giao tiếp cho phép một chương trình tiếp tục chạy thậm chí nếu một phần của nó bị khóa hay đang thực hiện một thao tác dài, do đó gia tăng sự đáp ứng đối với người dùng. Thí dụ, một trình duyệt web vẫn có thể đáp ứng người dùng bằng một luồng trong khi một ảnh đang được nạp bằng một luồng khác.
2.Chia sẻ tài nguyên: Mặc định, các luồng chia sẻ bộ nhớ và các tài nguyên của các quá trình mà chúng thuộc về. Thuận lợi của việc chia sẽ mã là nó cho phép một ứng dụng có nhiều hoạt động của các luồng khác nhau nằm trong cùng không gian địa chỉ.
3.Kinh tế: cấp phát bộ nhớ và các tài nguyên cho việc tạo các quá trình là rất
đắt. Vì các luồng chia sẻ tài nguyên của quá trình mà chúng thuộc về nên nó kinh tế hơn để tạo và chuyển ngữ cảnh giữa các luồng. Khó để đánh giá theo kinh nghiệm sự khác biệt chi phí cho việc tạo và duy trì một quá trình hơn một luồng, nhưng thường nó sẽ mất nhiều thời gian để tạo và quản lý một quá trình hơn một luồng. Trong Solaris 2, tạo một quá trình chậm hơn khoảng 30 lần tạo một luồng và chuyển đổi ngữ cảnh chậm hơn 5 lần.
4.Sử dụng kiến trúc đa xử lý: các lợi điểm của đa luồng có thể phát huy trong
kiến trúc đa xử lý, ở đó mỗi luồng thực thi song song trên một bộ xử lý khác nhau. Một quá trình đơn luồng chỉ có thể chạy trên một CPU. Đa luồng trên một máy nhiều CPU gia tăng tính đồng hành. Trong kiến trúc đơn xử lý, CPU thường chuyển đổi qua lại giữa mỗi luồng quá nhanh để tạo ra hình ảnh của sự song song nhưng trong thực tế chỉ một luồng đang chạy tại một thời điểm.
1.Sự đáp ứng: đa luồng một ứng dụng giao tiếp cho phép một chương trình tiếp tục chạy thậm chí nếu một phần của nó bị khóa hay đang thực hiện một thao tác dài, do đó gia tăng sự đáp ứng đối với người dùng. Thí dụ, một trình duyệt web vẫn có thể đáp ứng người dùng bằng một luồng trong khi một ảnh đang được nạp bằng một luồng khác.
2.Chia sẻ tài nguyên: Mặc định, các luồng chia sẻ bộ nhớ và các tài nguyên của các quá trình mà chúng thuộc về. Thuận lợi của việc chia sẽ mã là nó cho phép một ứng dụng có nhiều hoạt động của các luồng khác nhau nằm trong cùng không gian địa chỉ.
3.Kinh tế: cấp phát bộ nhớ và các tài nguyên cho việc tạo các quá trình là rất
đắt. Vì các luồng chia sẻ tài nguyên của quá trình mà chúng thuộc về nên nó kinh tế hơn để tạo và chuyển ngữ cảnh giữa các luồng. Khó để đánh giá theo kinh nghiệm sự khác biệt chi phí cho việc tạo và duy trì một quá trình hơn một luồng, nhưng thường nó sẽ mất nhiều thời gian để tạo và quản lý một quá trình hơn một luồng. Trong Solaris 2, tạo một quá trình chậm hơn khoảng 30 lần tạo một luồng và chuyển đổi ngữ cảnh chậm hơn 5 lần.
4.Sử dụng kiến trúc đa xử lý: các lợi điểm của đa luồng có thể phát huy trong
kiến trúc đa xử lý, ở đó mỗi luồng thực thi song song trên một bộ xử lý khác nhau. Một quá trình đơn luồng chỉ có thể chạy trên một CPU. Đa luồng trên một máy nhiều CPU gia tăng tính đồng hành. Trong kiến trúc đơn xử lý, CPU thường chuyển đổi qua lại giữa mỗi luồng quá nhanh để tạo ra hình ảnh của sự song song nhưng trong thực tế chỉ một luồng đang chạy tại một thời điểm.
DuongTrungTinh(I11C)- Tổng số bài gửi : 31
Join date : 26/08/2011
Re: Thảo luận Bài 5 (Đa luồng)
NguyThiGai (I11C) đã viết:Chào bạn VoMinhHoang (I11C)!VoMinhHoang (I11C) đã viết:Đa luồng dùng chung các tiến trình trong hệ thống, quản trị công việc bên trong cấp phát giữa các tiến trình. (vd: tài nguyên dùng chung là bảng lớp học)
Tiến trình truyền thống dùng chung các tiến trình bên ngoài. Lập trình đa luồng dễ hơn lập trình đa tiến trình (như tạo mới luồng, chia sẻ, điều khiển dễ hơn..)
Giống nhau:
Đều có thông tin trạng thái
Luồng còn được gọi là tiến trình nhẹ
Nhiều luồng hoặc nhiều tiến trình có thể liên quan đến một chu trình
Chia sẻ tài nguyên cho nhau, tăng tốc tính toán, đảm bảo tính đơn thể
Khác nhau:
Do luồng cùng vận hành trong 1 vùng địa chỉ, vì vậy dễ dùng chung tài nguyên hơn đa tiến trình ví dụ mượn đồ trong gia đình dễ mượn đồ hơn của hàng xóm
Do luồng chung tài nguyên với luồng cha nên việc tạo lập và chuyển đổi ngữ cảnh cũng nhanh hơn tiến trình
Ví dụ: việc ngăn riêng ra một phòng trong nhà thì dễ hơn được nhà nước cấp cho một căn hộ
Cấp phát tài nguyên cho bộ nhớ thì tốn kém
Có một vấn đề mình không hiểu trong phần so sánh khác nhau giữa tiến trình và luồng. Bạn giải thích giúp nhé!
Mình không hiểu luồng cha đây là luồng gì?
-Theo như Thầy giảng trên lớp: Trong 1 tiến trình có thể có nhiều tiến trình con nhưng trong 1 luồng thì không có luồng con. Vậy lấy đâu ra luồng cha? Mình thấy trong các bài viết của các bạn khác cũng thế. Mình không biết cái nào mới đúng.
Rất mong các bạn góp ý giúp!!!
Theo mình hiểu thì như thế này:
- Tiến trình thì có nhiều tiến trình (đa tiến trình): có tiến trình cha và có tiến trình con, tiến trình cha có nhiệm vụ điều khiển tiến trình con sao cho hợp lý trong khi HĐH xử lý.
-Luồng thì cũng có nhiều luồng (đa luồng): Cũng có luồng cha và luồng con, luồng cha cũng có nhiệm vụ điều khiển luồng con , khi xếp bậc cha con như vậy thì luồng con sẽ tồn tại trên cơ sở của luồng cha, tức là có thể dùng chung tài nguyên chẳng hạn.
Đó là ý kiến riêng của mình. Bạn nào thấy đúng sai thì cho ý kiến nhé.
Thanks!
DuongTrungTinh(I11C)- Tổng số bài gửi : 31
Join date : 26/08/2011
So Sanh Luong Voi Tien Trinh
Khái niệm đa luồng: Luồng còn gọi là tiến trình nhẹ (LWP-Light Weight Process), cũng là một đơn vị cơ bản sử dụng CPU.
* So sánh:
- Tiến trình (Process) là chuơng trình trong thời gian thực hiện (đặt dưới sự quản lý của HĐH).
- Luồng (Thread) còn gọi là tiến trình nhẹ (LWP-Light Weight Process), một đơn vị cơ bản sử dụng CPU.
- Luồng cũng có thông tin trạng thái như của tiến trình truyền thống (HWP- Heavy Weight Process).
- Tiến trình có thể có một luồng chính với nhiều luồng phụ. Mỗi luồng có khả năng chia sẻ tài nguyên với các luồng khác trong tiến trình.
- Nhiều luồng có thể cùng chung một mã chương trình
* So sánh:
- Tiến trình (Process) là chuơng trình trong thời gian thực hiện (đặt dưới sự quản lý của HĐH).
- Luồng (Thread) còn gọi là tiến trình nhẹ (LWP-Light Weight Process), một đơn vị cơ bản sử dụng CPU.
- Luồng cũng có thông tin trạng thái như của tiến trình truyền thống (HWP- Heavy Weight Process).
- Tiến trình có thể có một luồng chính với nhiều luồng phụ. Mỗi luồng có khả năng chia sẻ tài nguyên với các luồng khác trong tiến trình.
- Nhiều luồng có thể cùng chung một mã chương trình
TranVuThuyVan_(I11C)- Tổng số bài gửi : 11
Join date : 26/08/2011
Ví dụ về đa luồng
Ví dụ này mình sẽ mô tả 2 luồng (cho đơn giản) được thực thi cùng một lúc.
Ở đây thì bạn cứ tưởng tượng ra rằng có hai thằng tên là A và B thi đếm từ 0 cho đến 100, thằng nào đếm xong trước thì báo cáo và được về chỗ. Tương ứng mình sẽ tạo ra 2 phương thức A() và B() (mỗi luồng sẽ xử lý một thằng).
void A()
{
for(int i=0; i<=100; i++)
{
Console.WriteLine(i.ToString());
}
Console.WriteLine("A đã đọc xong"); // Báo cáo đã đọc xong
}
void B()
{
for(int i=0; i<=100; i++)
{
Console.WriteLine(i.ToString());
}
Console.WriteLine("B đã đọc xong"); // Báo cáo đã đọc xong
}
Bây giờ thầy giáo (hoặc là bạn) bỗng cao hứng gọi 2 thằng lên thi đọc --> 2 thằng A và B cùng đọc Đến đây trong phương thức hàm main() của chương trình bạn sẽ phải gọi 2 thằng này
static void main()
{
ThreadStart ts1 = new ThreadStart(A); // Chỉ định thằng A lên đọc
ThreadStart ts2 = new ThreadStart(B); // Chỉ định thằng B lên đọc
// Sẵn sàng cho cuộc đấu (thi đếm nhanh )
Thread tA = new Thread(ts1);
Thread tB = new Thread(ts2);
// Bắt đầu bấm giờ
tA.Start();
tB.Start();
tA.Join();
tB.Join();
// Hai thằng tranh nhau đếm
Console.WriteLine("Cuộc thi kết thúc"); // Chờ đến khi 2 thằng đọc xong, không biết thằng nào sẽ thắng
Console.ReadLine();
}
// Thư viện tham chiếu nằm trong namespace System.Threading;
// Bạn cần khai báo sử dụng nó using Sytem.Threading;
Ở đây thì bạn cứ tưởng tượng ra rằng có hai thằng tên là A và B thi đếm từ 0 cho đến 100, thằng nào đếm xong trước thì báo cáo và được về chỗ. Tương ứng mình sẽ tạo ra 2 phương thức A() và B() (mỗi luồng sẽ xử lý một thằng).
void A()
{
for(int i=0; i<=100; i++)
{
Console.WriteLine(i.ToString());
}
Console.WriteLine("A đã đọc xong"); // Báo cáo đã đọc xong
}
void B()
{
for(int i=0; i<=100; i++)
{
Console.WriteLine(i.ToString());
}
Console.WriteLine("B đã đọc xong"); // Báo cáo đã đọc xong
}
Bây giờ thầy giáo (hoặc là bạn) bỗng cao hứng gọi 2 thằng lên thi đọc --> 2 thằng A và B cùng đọc Đến đây trong phương thức hàm main() của chương trình bạn sẽ phải gọi 2 thằng này
static void main()
{
ThreadStart ts1 = new ThreadStart(A); // Chỉ định thằng A lên đọc
ThreadStart ts2 = new ThreadStart(B); // Chỉ định thằng B lên đọc
// Sẵn sàng cho cuộc đấu (thi đếm nhanh )
Thread tA = new Thread(ts1);
Thread tB = new Thread(ts2);
// Bắt đầu bấm giờ
tA.Start();
tB.Start();
tA.Join();
tB.Join();
// Hai thằng tranh nhau đếm
Console.WriteLine("Cuộc thi kết thúc"); // Chờ đến khi 2 thằng đọc xong, không biết thằng nào sẽ thắng
Console.ReadLine();
}
// Thư viện tham chiếu nằm trong namespace System.Threading;
// Bạn cần khai báo sử dụng nó using Sytem.Threading;
PhamAnhKhoa(I11C)- Tổng số bài gửi : 13
Join date : 28/08/2011
Trang 3 trong tổng số 6 trang • 1, 2, 3, 4, 5, 6
Similar topics
» Thảo luận Bài 3
» Thảo luận Bài 5
» Thảo luận về những lợi ích của công nghệ đa luồng.
» Thảo luận về tại sao dùng nhiều nhiều luồng mà không dùng nhiều tiến trình
» Thảo luận Bài 4
» Thảo luận Bài 5
» Thảo luận về những lợi ích của công nghệ đa luồng.
» Thảo luận về tại sao dùng nhiều nhiều luồng mà không dùng nhiều tiến trình
» Thảo luận Bài 4
Trang 3 trong tổng số 6 trang
Permissions in this forum:
Bạn không có quyền trả lời bài viết