text:
Thảo luận Bài 5
Trang 1 trong tổng số 3 trang • Share •
Trang 1 trong tổng số 3 trang • 1, 2, 3
Thảo luận Bài 5
Thảo luận những vấn đề liên quan đến Bài 5.
- Attachments
Được sửa bởi Admin ngày 6/4/2014, 08:57; sửa lần 1.
Admin
- Admin
- Tổng số bài gửi : 285
Join date : 18/02/2009
-
Bài toán Producer/Consumer
Nhận xét:
• Tổ chức buffer có dạng xoay vòng (circular buffer)
• Producer nhanh hơn: mất dữ liệu
• Consumer nhanh hơn: trùng dữ liệu
Giải quyết:
#define N 100 /* kích thước buffer */
typedef int semaphore; /* kiểu semaphore */
semaphore mutex = 1; /* mutex loại trừ tương hỗ */
semaphore empty = N; /* số phần tử trống */
semaphore full = 0; /* số phần tử có dữ liệu */
void producer(void)
{
int item; /* phần tử dữ liệu */
while (TRUE){
produce_item(&item); /* tạo dữ liệu */
down(&empty); /* giảm số phần tử trống */
down(&mutex); /* vào vùng tranh chấp */
enter_item(item); /* ghi dữ liệu */
up(&mutex); /* rời vùng tranh chấp */
up(&full); /* tăng số phần tử có dữ liệu */
}
}
void consumer(void)
{
int item;
while (TRUE){
down(&full); /* giảm số phần tử có dữ liệu */
down(&mutex); /* vào vùng tranh chấp */
remove_item(&item); /* loại bỏ dữ liệu */
up(&mutex); /* rời vùng tranh chấp */
up(&empty); /* tăng số phần tử trống */
consume_item(item); /* dùng item */
}
}
• Tổ chức buffer có dạng xoay vòng (circular buffer)
• Producer nhanh hơn: mất dữ liệu
• Consumer nhanh hơn: trùng dữ liệu
Giải quyết:
#define N 100 /* kích thước buffer */
typedef int semaphore; /* kiểu semaphore */
semaphore mutex = 1; /* mutex loại trừ tương hỗ */
semaphore empty = N; /* số phần tử trống */
semaphore full = 0; /* số phần tử có dữ liệu */
void producer(void)
{
int item; /* phần tử dữ liệu */
while (TRUE){
produce_item(&item); /* tạo dữ liệu */
down(&empty); /* giảm số phần tử trống */
down(&mutex); /* vào vùng tranh chấp */
enter_item(item); /* ghi dữ liệu */
up(&mutex); /* rời vùng tranh chấp */
up(&full); /* tăng số phần tử có dữ liệu */
}
}
void consumer(void)
{
int item;
while (TRUE){
down(&full); /* giảm số phần tử có dữ liệu */
down(&mutex); /* vào vùng tranh chấp */
remove_item(&item); /* loại bỏ dữ liệu */
up(&mutex); /* rời vùng tranh chấp */
up(&empty); /* tăng số phần tử trống */
consume_item(item); /* dùng item */
}
}
NguyenVietLong08(HLT3)
- Tổng số bài gửi : 20
Join date : 30/03/2014
-
Đa Luồng
Đa luồng là một kỹ thuật cho phép một chương trình hoặc một quá trình để thực hiện nhiều nhiệm vụ đồng thời (cùng một lúc và song song). Nó cho phép một quá trình để chạy các nhiệm vụ của nó trong chế độ song song trên một hệ thống xử lý duy nhất
Trong khái niệm xử lý đa luồng, một số quá trình nhiều nhẹ đang chạy trong một tiến trình / chương trình, nhiệm vụ hoặc một bộ xử lý duy nhất. Ví dụ, bạn sử dụng một trình xử lý, bạn thực hiện nhiều nhiệm vụ khác nhau như in ấn, kiểm tra chính tả và như vậy. Phần mềm đa luồng xử lý mỗi quá trình như là một chương trình riêng biệt.
Trong Java, Java Virtual Machine (JVM) cho phép một ứng dụng có nhiều chủ đề thực hiện chạy đồng thời. Nó cho phép một chương trình có trách nhiệm hơn cho người sử dụng. Khi một chương trình có nhiều chủ đề sau đó CPU có thể chuyển đổi giữa hai chủ đề để thực hiện chúng cùng một lúc.
Ví dụ, nhìn vào sơ đồ hiển thị như sau:
[url=[url=][/url]]Da luong[/url]
Trong sơ đồ này, hai chủ đề đang được thực hiện có nhiều hơn một nhiệm vụ. Nhiệm vụ của mỗi thread được chuyển sang các nhiệm vụ của các chủ đề khác.
Ví dụ nguyên lý tập Luồng
Trong một cửa hàng làm tóc, có rất nhiều nhân viên hớt tóc, làm móng... (tương ứng là các luồng con)
Cứ mỗi người nhân viên, sẽ chịu trách nhiệm phục vụ cho khách hàng của mình (mỗi luồng có thể chạy bởi CPU riêng), do đó có bao nhiêu nhân viên trong tiệm hớt tóc thì sẽ tương ứng với số luồng trong tập luồng
Số lượng luồng càng nhiều khả năng đáp ứng càng cao
Khi có khách hàng đến, thì nhân viên nào đang trống khách (đang ngồi chơi # đang ngủ) thì sẽ phục vụ cho khách hàng ( luồng được nhân yêu cầu, được đánh thức và đưa vào vận hành) khi phục vụ xong nhân viên được tạm nghỉ giải lao chờ có khách hàng mới (luồng trả về tập luồng)
Nếu số lượng khách hàng quá đông, hơn số lượng nhân viên, thì khách hàng sẽ xếp hàng đợi đến khi có 1 nhân viên rảnh (1 luồng được giải phóng)
Trong khái niệm xử lý đa luồng, một số quá trình nhiều nhẹ đang chạy trong một tiến trình / chương trình, nhiệm vụ hoặc một bộ xử lý duy nhất. Ví dụ, bạn sử dụng một trình xử lý, bạn thực hiện nhiều nhiệm vụ khác nhau như in ấn, kiểm tra chính tả và như vậy. Phần mềm đa luồng xử lý mỗi quá trình như là một chương trình riêng biệt.
Trong Java, Java Virtual Machine (JVM) cho phép một ứng dụng có nhiều chủ đề thực hiện chạy đồng thời. Nó cho phép một chương trình có trách nhiệm hơn cho người sử dụng. Khi một chương trình có nhiều chủ đề sau đó CPU có thể chuyển đổi giữa hai chủ đề để thực hiện chúng cùng một lúc.
Ví dụ, nhìn vào sơ đồ hiển thị như sau:
[url=[url=][/url]]Da luong[/url]
Trong sơ đồ này, hai chủ đề đang được thực hiện có nhiều hơn một nhiệm vụ. Nhiệm vụ của mỗi thread được chuyển sang các nhiệm vụ của các chủ đề khác.
Ví dụ nguyên lý tập Luồng
Trong một cửa hàng làm tóc, có rất nhiều nhân viên hớt tóc, làm móng... (tương ứng là các luồng con)
Cứ mỗi người nhân viên, sẽ chịu trách nhiệm phục vụ cho khách hàng của mình (mỗi luồng có thể chạy bởi CPU riêng), do đó có bao nhiêu nhân viên trong tiệm hớt tóc thì sẽ tương ứng với số luồng trong tập luồng
Số lượng luồng càng nhiều khả năng đáp ứng càng cao
Khi có khách hàng đến, thì nhân viên nào đang trống khách (đang ngồi chơi # đang ngủ) thì sẽ phục vụ cho khách hàng ( luồng được nhân yêu cầu, được đánh thức và đưa vào vận hành) khi phục vụ xong nhân viên được tạm nghỉ giải lao chờ có khách hàng mới (luồng trả về tập luồng)
Nếu số lượng khách hàng quá đông, hơn số lượng nhân viên, thì khách hàng sẽ xếp hàng đợi đến khi có 1 nhân viên rảnh (1 luồng được giải phóng)
Giới Thiệu Một Số Loại Luồng
Luồng Windows 2000
Windows 2000 cài đặt Win32 API. Win32 API là một API chủ yếu cho họ hệ điều hành Windows (Windows 95/98/NT và Windows 2000). Thực vậy, những gì được đề cập trong phần phần này áp dụng tới họ hệ điều hành nàyỨng dụng Windows chạy như một tiến trình riêng rẻ nơi mỗi tiến trình có thể chứa một hay nhiều luồng. Windows 2000 dùng ánh xạ một-một nơi mà mỗi luồng cấp người dùng ánh xạ tới luồng nhân được liên kết tới.Tuy nhiên, Windows cũng cung cấp sự hỗ trợ cho một thư viện có cấu trúc (fiber library) cung cấp chức năng của mô hình nhiều-nhiều. Mỗi luồng thuộc về một tiến trình có thể truy xuất một không gian địa chỉ ảo của tiến trình.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).Tập thanh ghi, ngăn xếp và vùng lưu trữ riêng được xem như ngữ cảnh của luồng và được đặc tả kiến trúc tới phần cứng mà hệ điều hành chạy trên đó. 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 tiến 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)
Luồng Linux
Nhân Linux được giới thiệu trong ấn bản 2.2. Linux cung cấp một lời gọi hệ thống fork với chức năng truyền thống là tạo bản sao một tiến trình . Linux cũng cung cấp lời gọi hệ thống clone mà nó tương tự như tạo một luồng. clone có hành vi rất giống như fork, ngoại trừ thay vì tạo một bản sao của tiến trình gọi, nó tạo một tiến trình riêng chia sẻ không gian địa chỉ của tiến trình gọi. Nó chấm dứt việc chia sẻ không gian địa chỉ của tiến trình cha mà một tác vụ được nhân bản đối xử giống rất nhiều một luồng riêng rẻ.Chia sẻ không gian địa chỉ được cho phép vì việc biểu diễn của một tiến trình trong nhân Linux. Một cấu trúc dữ liệu nhân duy nhất tồn tại cho mỗi tiến trình trong hệ thống. Một cấu trúc dữ liệu nhân duy nhất tồn tại cho mỗi tiến trình trong hệ thống. Tuy nhiên, tốt hơn lưu trữ dữ liệu cho mỗi tiến trình trong cấu trúc dữ liệu là nó chứa các con trỏ chỉ tới các cấu trúc dữ liệu khác nơi dữ liệu này được được lưu. Ví dụ, cấu trúc dữ liệu trên tiến trình chứa các con trỏ chỉ tới các cấu trúc dữ liệu khác hiện diện danh sách tập tin đang mở, thông tin quản lý tín hiệu, và bộ nhớ ảo. Khi fork được gọi, một tiến trình mới được tạo cùng với một bản sao của tất cả cấu trúc dữ liệu của tiến trình cha được liên kết tới. Khi lời gọi hệ thống clone được thực hiện, một tiến trình mới chỉ tới cấu trúc dữ liệu của tiến trình cha, do đó cho phép tiến trình con chia sẻ bộ nhớ và tài nguyên của tiến trình cha. Một tập hợp cờ được truyền như một tham số tới lời gọi hệ thống clone. Tập hợp cờ này được dùng để hiển thị bao nhiêu tiến trình cha được chia sẻ với tiến trình con. Nếu không có cờ nào được đặt, không có chia sẻ xảy ra và clone hoạt động giống như fork. Nếu tất cả năm cờ được đặt, tiến trình con chia sẻ mọi thứ với tiến trình cha. Sự kết hợp khác của cờ cho phép các cấp độ chia sẻ khác nhau giữa hai mức độ cao nhất này. Điều thú vị là Linux không phân biệt giữa tiến trình và luồng. Thật vậy, Linux thường sử dụng thuật ngữ tác vụ-hơn là tiến trình hay luồng-khi tham chiếu tới dòng điều khiển trong chương trình. Ngoài tiến trình được nhân bản, Linux không hỗ trợ đa luồng, cấu trúc dữ liệu riêng hay thủ tục nhân. Tuy nhiên, những cài đặt Pthreads là sẳn dùng cho đa luồng cấp người dùng.
Luồng Java
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.
Windows 2000 cài đặt Win32 API. Win32 API là một API chủ yếu cho họ hệ điều hành Windows (Windows 95/98/NT và Windows 2000). Thực vậy, những gì được đề cập trong phần phần này áp dụng tới họ hệ điều hành nàyỨng dụng Windows chạy như một tiến trình riêng rẻ nơi mỗi tiến trình có thể chứa một hay nhiều luồng. Windows 2000 dùng ánh xạ một-một nơi mà mỗi luồng cấp người dùng ánh xạ tới luồng nhân được liên kết tới.Tuy nhiên, Windows cũng cung cấp sự hỗ trợ cho một thư viện có cấu trúc (fiber library) cung cấp chức năng của mô hình nhiều-nhiều. Mỗi luồng thuộc về một tiến trình có thể truy xuất một không gian địa chỉ ảo của tiến trình.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).Tập thanh ghi, ngăn xếp và vùng lưu trữ riêng được xem như ngữ cảnh của luồng và được đặc tả kiến trúc tới phần cứng mà hệ điều hành chạy trên đó. 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 tiến 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)
Luồng Linux
Nhân Linux được giới thiệu trong ấn bản 2.2. Linux cung cấp một lời gọi hệ thống fork với chức năng truyền thống là tạo bản sao một tiến trình . Linux cũng cung cấp lời gọi hệ thống clone mà nó tương tự như tạo một luồng. clone có hành vi rất giống như fork, ngoại trừ thay vì tạo một bản sao của tiến trình gọi, nó tạo một tiến trình riêng chia sẻ không gian địa chỉ của tiến trình gọi. Nó chấm dứt việc chia sẻ không gian địa chỉ của tiến trình cha mà một tác vụ được nhân bản đối xử giống rất nhiều một luồng riêng rẻ.Chia sẻ không gian địa chỉ được cho phép vì việc biểu diễn của một tiến trình trong nhân Linux. Một cấu trúc dữ liệu nhân duy nhất tồn tại cho mỗi tiến trình trong hệ thống. Một cấu trúc dữ liệu nhân duy nhất tồn tại cho mỗi tiến trình trong hệ thống. Tuy nhiên, tốt hơn lưu trữ dữ liệu cho mỗi tiến trình trong cấu trúc dữ liệu là nó chứa các con trỏ chỉ tới các cấu trúc dữ liệu khác nơi dữ liệu này được được lưu. Ví dụ, cấu trúc dữ liệu trên tiến trình chứa các con trỏ chỉ tới các cấu trúc dữ liệu khác hiện diện danh sách tập tin đang mở, thông tin quản lý tín hiệu, và bộ nhớ ảo. Khi fork được gọi, một tiến trình mới được tạo cùng với một bản sao của tất cả cấu trúc dữ liệu của tiến trình cha được liên kết tới. Khi lời gọi hệ thống clone được thực hiện, một tiến trình mới chỉ tới cấu trúc dữ liệu của tiến trình cha, do đó cho phép tiến trình con chia sẻ bộ nhớ và tài nguyên của tiến trình cha. Một tập hợp cờ được truyền như một tham số tới lời gọi hệ thống clone. Tập hợp cờ này được dùng để hiển thị bao nhiêu tiến trình cha được chia sẻ với tiến trình con. Nếu không có cờ nào được đặt, không có chia sẻ xảy ra và clone hoạt động giống như fork. Nếu tất cả năm cờ được đặt, tiến trình con chia sẻ mọi thứ với tiến trình cha. Sự kết hợp khác của cờ cho phép các cấp độ chia sẻ khác nhau giữa hai mức độ cao nhất này. Điều thú vị là Linux không phân biệt giữa tiến trình và luồng. Thật vậy, Linux thường sử dụng thuật ngữ tác vụ-hơn là tiến trình hay luồng-khi tham chiếu tới dòng điều khiển trong chương trình. Ngoài tiến trình được nhân bản, Linux không hỗ trợ đa luồng, cấu trúc dữ liệu riêng hay thủ tục nhân. Tuy nhiên, những cài đặt Pthreads là sẳn dùng cho đa luồng cấp người dùng.
Luồng Java
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.
Đa Luồng
đa luồng:
- Mỗi luồng có thể dùng chung và chia sẻ nguồn tài nguyên trong quá trình chạy, nhưng có thể thực hiện một cách độc lập.
- Ứng dụng trách nhiệm có thể được tách
+ Luồng chính chạy giao diện người dung
+ Các luồng phụ nhiệm gửi đến luồng chính.
- Luồng mang tính chất trừu tượng
- Một chương trình đa luồng hoạt động nhanh hơn trên máy tính có cấu hình tốt và mạnh
* Nhược điểm của đa luồng:
- Càng nhiều luồng thì xử lý càng phức tạp
- Cần phát hiện tránh các luồng chết, luồng chạy mà không làm gì trong ứng dụng cảận những vấn đề liên quan đến Bài 5.[/quote]
- Mỗi luồng có thể dùng chung và chia sẻ nguồn tài nguyên trong quá trình chạy, nhưng có thể thực hiện một cách độc lập.
- Ứng dụng trách nhiệm có thể được tách
+ Luồng chính chạy giao diện người dung
+ Các luồng phụ nhiệm gửi đến luồng chính.
- Luồng mang tính chất trừu tượng
- Một chương trình đa luồng hoạt động nhanh hơn trên máy tính có cấu hình tốt và mạnh
* Nhược điểm của đa luồng:
- Càng nhiều luồng thì xử lý càng phức tạp
- Cần phát hiện tránh các luồng chết, luồng chạy mà không làm gì trong ứng dụng cảận những vấn đề liên quan đến Bài 5.[/quote]
NguyenHuuSonLam(TH10A1)
- Tổng số bài gửi : 35
Join date : 14/03/2014
-
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
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
vothihongngoc72 (HLT3)
- Tổng số bài gửi : 28
Join date : 16/03/2014
-
Phân biệt khái niệm luồng và tiến trình, những ích lợi của công nghệ đa luồng
a) Khái niệm luồng ( thread )
+ Luồng 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 của tiến trình truyền thống ( HWP – Heavy Weight Process ).
+ Một luồng là một dòng xử lý cơ bản trong hệ thống. Mỗi luồng xử lý tuần tự đoạn code của nó, sở hữu một con trỏ lệnh, tập các thanh ghi và một vùng nhớ stack riêng-> luồng bao gồm: mã luồng ( thread ID ) + bộ đếm chương trình ( program counter ) + tập thanh ghi ( register set ) + stack.
b) Khái niệm tiến trình ( process)
+ Việc thực hiện các công việc được mô tả thông qua chương trình-> chương trình hoạt động thì chuyển thành tiến trình-> một tiến trình gồm:mã nguồn chương trình (code ) + data + bộ đếm chương trình ( program counter ) + ngăn xếp ( stack ) + giá trị ở các thanh ghi ( register values )-> một tiến trình cần: cung cấp đầy đủ tài nguyên cần thiết + CPU tiếp nhận và thực hiện.
+ Tiến trình có thể có một luồng chính với nhiều luồng phụ.
c) Phân biệt luồng và tiến trình
+ Luồng được coi là mức thấp hơn của tiến trình, mỗi tiến trình có thể có nhiều luồng.
+ Hoạt động của các luồng giống như tiến trình nhưng các luồng cùng chia sẻ không gian địa chỉ chung, còn các tiến trình thì hoàn toàn độc lập.
d) Trình bày những ích lợi của công nghệ đa luồng.
+ Đáp ứng nhanh ( responsiveness ): cho phép luồng chính tiếp tục được thực hiện thậm chí khi một luồng bị ách hoặc quá bận.
+ Chia sẻ tài nguyên ( resource sharing ): các luồng có thể dùng chung bộ nhớ và tài nguyên của luồng cha, cho phép 1 ứng dụng có 1 số luồng khác nhau hoạt động trong cùng 1 không gian địa chỉ.
+ 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 nên việc tạo lập và chuyển ngữ cảnh cũng nhanh hơn.
+ Tận dụng được thế mạnh của kiến trúc đa xử lý ( multiprocessor ): làm tăng tính song song trên hệ máy nhiều CPU ( processor ).
+ Lập trình đa luồng dễ hơn lập trình đa tiến trình, tạo mới 1 tiến trình vừa lâu vừa khó, tạo mới 1 luồng thì nhanh và dễ hơn.
+ Luồng 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 của tiến trình truyền thống ( HWP – Heavy Weight Process ).
+ Một luồng là một dòng xử lý cơ bản trong hệ thống. Mỗi luồng xử lý tuần tự đoạn code của nó, sở hữu một con trỏ lệnh, tập các thanh ghi và một vùng nhớ stack riêng-> luồng bao gồm: mã luồng ( thread ID ) + bộ đếm chương trình ( program counter ) + tập thanh ghi ( register set ) + stack.
b) Khái niệm tiến trình ( process)
+ Việc thực hiện các công việc được mô tả thông qua chương trình-> chương trình hoạt động thì chuyển thành tiến trình-> một tiến trình gồm:mã nguồn chương trình (code ) + data + bộ đếm chương trình ( program counter ) + ngăn xếp ( stack ) + giá trị ở các thanh ghi ( register values )-> một tiến trình cần: cung cấp đầy đủ tài nguyên cần thiết + CPU tiếp nhận và thực hiện.
+ Tiến trình có thể có một luồng chính với nhiều luồng phụ.
c) Phân biệt luồng và tiến trình
+ Luồng được coi là mức thấp hơn của tiến trình, mỗi tiến trình có thể có nhiều luồng.
+ Hoạt động của các luồng giống như tiến trình nhưng các luồng cùng chia sẻ không gian địa chỉ chung, còn các tiến trình thì hoàn toàn độc lập.
d) Trình bày những ích lợi của công nghệ đa luồng.
+ Đáp ứng nhanh ( responsiveness ): cho phép luồng chính tiếp tục được thực hiện thậm chí khi một luồng bị ách hoặc quá bận.
+ Chia sẻ tài nguyên ( resource sharing ): các luồng có thể dùng chung bộ nhớ và tài nguyên của luồng cha, cho phép 1 ứng dụng có 1 số luồng khác nhau hoạt động trong cùng 1 không gian địa chỉ.
+ 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 nên việc tạo lập và chuyển ngữ cảnh cũng nhanh hơn.
+ Tận dụng được thế mạnh của kiến trúc đa xử lý ( multiprocessor ): làm tăng tính song song trên hệ máy nhiều CPU ( processor ).
+ Lập trình đa luồng dễ hơn lập trình đa tiến trình, tạo mới 1 tiến trình vừa lâu vừa khó, tạo mới 1 luồng thì nhanh và dễ hơn.
vấn đề khi download
sao em không down được bài của thầy
ATTACHMENTS
SanXuatTieuThu C# .NET 2005.zip
You don't have permission to download attachments.
(64 Kb) Downloaded 1 times
Admin: Bây giờ được rồi đấy !
ATTACHMENTS
SanXuatTieuThu C# .NET 2005.zip
You don't have permission to download attachments.
(64 Kb) Downloaded 1 times
Admin: Bây giờ được rồi đấy !
Được sửa bởi NguyễnMinhHoàng45(HLT3) ngày 6/4/2014, 18:34; sửa lần 1.
Trình bày nguyên lý và ích lợi củacông nghệ đa luồng(Phân biệt tiến trình với luồng, vấn đề chung mã chương trình)
* Phân biệt khái niệm luồng với tiến trình :
- Luồng: 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 hệ thống (HWP - Heavy Weight Process). Mỗi luồng có khả năng chia sẻ tài nguyên với các luồng khác trong 1 tiến trình...
- Tiến trình: là chương trình trong thời gian thực hiện (đặt dưới sự quản lý của hệ điều hành). Có sự phân biệt Tiến trình hệ thống (của Hệ điều hành) với Tiến trình người dùng. Tiến trình có thể có 1 luồng chính với nhiều luồng phụ.
* Những ích lợi 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ề).
- 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.
- 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).
- 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.
- Lập trình đa luồng dễ hơn lập trình đa tiến trình...
- Luồng: 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 hệ thống (HWP - Heavy Weight Process). Mỗi luồng có khả năng chia sẻ tài nguyên với các luồng khác trong 1 tiến trình...
- Tiến trình: là chương trình trong thời gian thực hiện (đặt dưới sự quản lý của hệ điều hành). Có sự phân biệt Tiến trình hệ thống (của Hệ điều hành) với Tiến trình người dùng. Tiến trình có thể có 1 luồng chính với nhiều luồng phụ.
* Những ích lợi 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ề).
- 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.
- 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).
- 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.
- Lập trình đa luồng dễ hơn lập trình đa tiến trình...
NguyenChiKien(HLT3)
- Tổng số bài gửi : 44
Join date : 23/03/2014
Age : 34
-
Re: Thảo luận Bài 5
Em k0 download đc...Admin đã viết:Thảo luận những vấn đề liên quan đến Bài 5.
Admin: Bây giờ được rồi đấy !
NguyenChiKien(HLT3)
- Tổng số bài gửi : 44
Join date : 23/03/2014
Age : 34
-
cải tiến Producer và Consumer để tránh bị lỗi
hàm Producer và Consumer gốc của thầy
em fix lại như sau, thầy xem thử nhé.
Admin:
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
- Code:
public void Producer(object id)
{
while(true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.buffer[Program.ptrIn] = NextProduced++;
Program.s[Program.ptrIn] = ((int)id) + 1;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000)); // DateTime.Now.Ticks represents the total number of ticks in local time (not) UTC since the DateTime epoch, which is midnight on January 1st in the year 1AD. (Each tick is 100 nanoseconds; there are 10,000 ticks in a millisecond)
}
}
public void Consumer(object id)
{
while (true)
{
while (Program.ptrIn==Program.ptrOut);
NextConsumed = Program.buffer[Program.ptrOut];
Program.buffer[Program.ptrOut] = -Program.buffer[Program.ptrOut];
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000));
}
}
em fix lại như sau, thầy xem thử nhé.
- Code:
void Produce(object id)
{
while (true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrIn == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrIn - 1;
Program.buffer[pos] = nextProducer++;
Program.producer[pos] = "P" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
void Comsume(object id)
{
while (true)
{
while (Program.ptrIn == Program.ptrOut) ;
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrOut == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrOut - 1;
nextConsumer = Program.buffer[pos];
Program.consumer[pos] = "C" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
Admin:
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
project Produce Consumer
đây là project em tự làm lúc chưa load được code thầy, có gì sai sót thầy chỉ giúp em nhé...
Admin: Tốt lắm !
Admin: Tốt lắm !
- Attachments
Hệ điều hành đa chương
Hệ điều hành đa chương là hệ điều hành có thể quản lý nhiều chương trình cùng một lúc được nạp vào trong bộ nhớ.
VD:
+ Hệ đa chương: Một người có thể làm nhiều công việc cùng một lúc như: vưa rửa chén, lau nhà, giặt quần áo...
VD:
+ Hệ đa chương: Một người có thể làm nhiều công việc cùng một lúc như: vưa rửa chén, lau nhà, giặt quần áo...
VoMinhThienHLT3
- Tổng số bài gửi : 9
Join date : 21/03/2014
-
SanXuatTieuThu
Thầy ơi! em down không đượcAdmin đã viết:Thảo luận những vấn đề liên quan đến Bài 5.
dangthituyetnhungTH08a1
- Tổng số bài gửi : 41
Join date : 19/03/2014
-
Re: Thảo luận Bài 5
Theo em có nhiều cách để điều khiển thread consumer đồng bộ với producer như đặt biến cờ, cho thread producer điều khiển thread consumer sleep weak up, tạo sự phụ thuộc consumer vào producer...NguyễnMinhHoàng45(HLT3) đã viết:hàm Producer và Consumer gốc của thầy
Em suy nghĩ về code này thì thấy có khả năng nếu 2 thread producer (or consumer) cùng chạy 1 time... thì sẽ dẫn đến cả 2 cái cùng vào đc qua while kiểm tra điều kiện. sau đó P1 ghi dữ liệu rồi tăng biến đếm sau, trong khi ghi dữ liệu thì P2 đã kịp chạy đến và ghi lên ngay sau đó cùng vị trí luôn. sau đó vị trí bị tăng lên 2 do cả 2 thread cùng chạy...
- Code:
public void Producer(object id)
{
while(true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.buffer[Program.ptrIn] = NextProduced++;
Program.s[Program.ptrIn] = ((int)id) + 1;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000)); // DateTime.Now.Ticks represents the total number of ticks in local time (not) UTC since the DateTime epoch, which is midnight on January 1st in the year 1AD. (Each tick is 100 nanoseconds; there are 10,000 ticks in a millisecond)
}
}
public void Consumer(object id)
{
while (true)
{
while (Program.ptrIn==Program.ptrOut);
NextConsumed = Program.buffer[Program.ptrOut];
Program.buffer[Program.ptrOut] = -Program.buffer[Program.ptrOut];
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000));
}
}
em fix lại như sau, thầy xem thử nhé.
- Code:
void Produce(object id)
{
while (true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrIn == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrIn - 1;
Program.buffer[pos] = nextProducer++;
Program.producer[pos] = "P" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
void Comsume(object id)
{
while (true)
{
while (Program.ptrIn == Program.ptrOut) ;
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrOut == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrOut - 1;
nextConsumer = Program.buffer[pos];
Program.consumer[pos] = "C" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
Admin:
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
PhanVietTrung(HLT3)
- Tổng số bài gửi : 25
Join date : 09/03/2014
-
Re: Thảo luận Bài 5
mỉnh thấy bạn hiểu sai vấn đề 1 chút. mình không cần đồng bộ giữa producer và consumer mà giữa chính producer với nhau, cũng như các consumer với nhau,vì 2 loại này hoạt động độc lập với nhau, nếu bạn tạo sự phụ thuộc là sai tinh thần thuật toán. có thể dùng 2 biến cờ để cùng lúc chỉ chạy 1 thread producer (consumer) nhưng mà dẫn đến 1 lúc chỉ có 1 cái làm... nếu như process lâu dẫn đến phải chờ cho xong mới đến lượt thread khác.PhanVietTrung(HLT3) đã viết:Theo em có nhiều cách để điều khiển thread consumer đồng bộ với producer như đặt biến cờ, cho thread producer điều khiển thread consumer sleep weak up, tạo sự phụ thuộc consumer vào producer...NguyễnMinhHoàng45(HLT3) đã viết:hàm Producer và Consumer gốc của thầy
Em suy nghĩ về code này thì thấy có khả năng nếu 2 thread producer (or consumer) cùng chạy 1 time... thì sẽ dẫn đến cả 2 cái cùng vào đc qua while kiểm tra điều kiện. sau đó P1 ghi dữ liệu rồi tăng biến đếm sau, trong khi ghi dữ liệu thì P2 đã kịp chạy đến và ghi lên ngay sau đó cùng vị trí luôn. sau đó vị trí bị tăng lên 2 do cả 2 thread cùng chạy...
- Code:
public void Producer(object id)
{
while(true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.buffer[Program.ptrIn] = NextProduced++;
Program.s[Program.ptrIn] = ((int)id) + 1;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000)); // DateTime.Now.Ticks represents the total number of ticks in local time (not) UTC since the DateTime epoch, which is midnight on January 1st in the year 1AD. (Each tick is 100 nanoseconds; there are 10,000 ticks in a millisecond)
}
}
public void Consumer(object id)
{
while (true)
{
while (Program.ptrIn==Program.ptrOut);
NextConsumed = Program.buffer[Program.ptrOut];
Program.buffer[Program.ptrOut] = -Program.buffer[Program.ptrOut];
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000));
}
}
em fix lại như sau, thầy xem thử nhé.
- Code:
void Produce(object id)
{
while (true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrIn == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrIn - 1;
Program.buffer[pos] = nextProducer++;
Program.producer[pos] = "P" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
void Comsume(object id)
{
while (true)
{
while (Program.ptrIn == Program.ptrOut) ;
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrOut == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrOut - 1;
nextConsumer = Program.buffer[pos];
Program.consumer[pos] = "C" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
Admin:
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
Re: Thảo luận Bài 5
NguyễnMinhHoàng45(HLT3) đã viết:mỉnh thấy bạn hiểu sai vấn đề 1 chút. mình không cần đồng bộ giữa producer và consumer mà giữa chính producer với nhau, cũng như các consumer với nhau,vì 2 loại này hoạt động độc lập với nhau, nếu bạn tạo sự phụ thuộc là sai tinh thần thuật toán. có thể dùng 2 biến cờ để cùng lúc chỉ chạy 1 thread producer (consumer) nhưng mà dẫn đến 1 lúc chỉ có 1 cái làm... nếu như process lâu dẫn đến phải chờ cho xong mới đến lượt thread khác.PhanVietTrung(HLT3) đã viết:Theo em có nhiều cách để điều khiển thread consumer đồng bộ với producer như đặt biến cờ, cho thread producer điều khiển thread consumer sleep weak up, tạo sự phụ thuộc consumer vào producer...NguyễnMinhHoàng45(HLT3) đã viết:hàm Producer và Consumer gốc của thầy
Em suy nghĩ về code này thì thấy có khả năng nếu 2 thread producer (or consumer) cùng chạy 1 time... thì sẽ dẫn đến cả 2 cái cùng vào đc qua while kiểm tra điều kiện. sau đó P1 ghi dữ liệu rồi tăng biến đếm sau, trong khi ghi dữ liệu thì P2 đã kịp chạy đến và ghi lên ngay sau đó cùng vị trí luôn. sau đó vị trí bị tăng lên 2 do cả 2 thread cùng chạy...
- Code:
public void Producer(object id)
{
while(true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.buffer[Program.ptrIn] = NextProduced++;
Program.s[Program.ptrIn] = ((int)id) + 1;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000)); // DateTime.Now.Ticks represents the total number of ticks in local time (not) UTC since the DateTime epoch, which is midnight on January 1st in the year 1AD. (Each tick is 100 nanoseconds; there are 10,000 ticks in a millisecond)
}
}
public void Consumer(object id)
{
while (true)
{
while (Program.ptrIn==Program.ptrOut);
NextConsumed = Program.buffer[Program.ptrOut];
Program.buffer[Program.ptrOut] = -Program.buffer[Program.ptrOut];
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000));
}
}
em fix lại như sau, thầy xem thử nhé.
- Code:
void Produce(object id)
{
while (true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrIn == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrIn - 1;
Program.buffer[pos] = nextProducer++;
Program.producer[pos] = "P" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
void Comsume(object id)
{
while (true)
{
while (Program.ptrIn == Program.ptrOut) ;
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrOut == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrOut - 1;
nextConsumer = Program.buffer[pos];
Program.consumer[pos] = "C" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
Admin:
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
Bạn còn nhớ ví dụ tập luồng chứ, thread có thể khởi tạo sẵn nhưng chưa chắc phải chạy ngay lúc nó khởi tạo, do đó ta có thể gọi nó khi nào cần thôi, tùy trường hợp sử dụng như thế nào mà chúng ta cần nó đồng bộ hay không, mình nghĩ bạn hiểu sai giữa đồng bộ, bất đồng bộ, xử lý song song và xử lý tuần tự.
PhanVietTrung(HLT3)
- Tổng số bài gửi : 25
Join date : 09/03/2014
-
Re: Thảo luận Bài 5
Nói như bạn trên thì khi cần Suppend Producer lại hoặc Suppend Consumer lại sẽ như thế nào, khi 1 cái chạy ảnh hưởng đến cái kia, cứ wake cái kia dậy???
Re: Thảo luận Bài 5
vả lại, mình và thầy đang trao đổi vì sự bất đồng bộ dữ liệu khi có 2 tiến trình Producer cùng chạy cùng lúc sẽ dẫn đến ghi dữ liệu sai vi trí (do vị trí chưa kịp cập nhật) bạn nhé... còn chuyện bạn nói là thuộc về thuật giải... có thể tiết kiệm tài nguyên bằng cách cho ngủ luồng Consumer khi Producer chưa sản xuất sau đó Producer sản xuất xong thì đánh thức dậy lấy... nó ảnh hưởng đến nguyên lý chung bài toán là Consumer và Producer độc lập với nhau không phụ thuộc nhau. Bạn có thể thấy điều này khi mà Consumer trước khi lấy phải kiểm tra còn hàng trong buffer không? nếu như cách bạn thì không cần kiểm tra. nếu như producer làm xong gọi consumer dậy lấy thì đó là cơ chế đút ăn bạn nhé...
Re: Thảo luận Bài 5
Tóm tắt bài 5
Ưu điểm và nhược điểm của một ứng dụng Multithreaded
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ể.
Ưu điểm và nhược điểm của một ứng dụng Multithreaded
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ể.
lekhacduyanh03(HLT3)
- Tổng số bài gửi : 12
Join date : 15/04/2013
Age : 26
-
Giới thiệu về lập trình Multithread trong C#
MultiThread, hiểu đơn giản là tạo 1 chương trình sao cho có hơn 1 luồng dữ liệu được xử lý trong đó. Ta thấy ở thời điểm hiện nay ngành công nghệ phần cứng đang phát triển mạnh mẽ, máy tính và các thiết bị di động được trang bị các bộ xử lý đa nhân để có thể làm được cùng một lúc nhiều công việc hơn – Xử lý song song. Việc phát triển chương trình chạy đa luồng cũng có ý nghĩa rất lớn bên ngành mạng viễn thông, giúp tăng tốc và cải thiện đường truyền tín hiệu.
Mình xin giới thiệu các bạn lập trình Thread trong C#.
Ta tạo ra 3 instances của lớp Thread và cho chúng start (để bắt đầu chạy), nhưng ta chỉ start 2 thread t1 và t2, nên ta sẽ thấy được chúng được in ra màn hình xen kẽ nhau, sau khi t1 và t2 kết thúc thì t3 bắt đầu được thực thi, mình xin giải thích sử dụng phương thức Join bên dưới.
using System;
using System.Threading;
namespace MultithreadDemo
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(a));
Thread t2 = new Thread(new ThreadStart(b));
Thread t3 = new Thread(new ThreadStart(c));
t1.Start();
t2.Start();
t1.Join();
t2.Join();
t3.Start();
Console.Read();
}
private static void c()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread c");
}
}
private static void b()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread b");
}
}
private static void a()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread a");
}
}
}
}
Join là một phương thức rất hay dùng khi xử lý Thread. Ta có thể hiểu ý nghĩa có phương thức này như sau: Khi một Thread gọi phương thức Join thì Thread đó sẽ được ưu tiên trong hệ thống. Những lện nào nằm sau phương thức Joinn chỉ được thực thi khi Thread kết thúc. Những lệnh đã chạy từ trước thì vẫn được thực thi với Thread hiện tại, và không có ảnh hưởng gì.
Mình xin giới thiệu các bạn lập trình Thread trong C#.
Ta tạo ra 3 instances của lớp Thread và cho chúng start (để bắt đầu chạy), nhưng ta chỉ start 2 thread t1 và t2, nên ta sẽ thấy được chúng được in ra màn hình xen kẽ nhau, sau khi t1 và t2 kết thúc thì t3 bắt đầu được thực thi, mình xin giải thích sử dụng phương thức Join bên dưới.
using System;
using System.Threading;
namespace MultithreadDemo
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(a));
Thread t2 = new Thread(new ThreadStart(b));
Thread t3 = new Thread(new ThreadStart(c));
t1.Start();
t2.Start();
t1.Join();
t2.Join();
t3.Start();
Console.Read();
}
private static void c()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread c");
}
}
private static void b()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread b");
}
}
private static void a()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread a");
}
}
}
}
Join là một phương thức rất hay dùng khi xử lý Thread. Ta có thể hiểu ý nghĩa có phương thức này như sau: Khi một Thread gọi phương thức Join thì Thread đó sẽ được ưu tiên trong hệ thống. Những lện nào nằm sau phương thức Joinn chỉ được thực thi khi Thread kết thúc. Những lệnh đã chạy từ trước thì vẫn được thực thi với Thread hiện tại, và không có ảnh hưởng gì.
NguyenTrungTruc(HLT3)
- Tổng số bài gửi : 17
Join date : 09/03/2014
-
Phân biệt khái niện luồng với tiến trình. Và trình bày những lợi ích của công nghệ đa luồng
Phân biệt khái niệm luồng với tiến trình
• Luồng: 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 hệ thống (HWP – Heavy Weight Process)
Ví dụ: Lớp học là một tiến trình. Trong lớp sẽ có một giáo viên(đơn luồng) và các học viên (đa luồng)
• Tiến trình: là chương trình trong thời gian thực hiện (đặt dưới sự quản lý của hệ điều hành). Có sự phân biệt Tiến trình hệ thống (của Hệ điều hành) với Tiến trình người dùng.
Ví dụ: Lớp HCTH102C đang học là một tiến trình
Những ích lợi 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, thì một trong các cô (cô thứ 1) 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 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.
• Luồng: 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 hệ thống (HWP – Heavy Weight Process)
Ví dụ: Lớp học là một tiến trình. Trong lớp sẽ có một giáo viên(đơn luồng) và các học viên (đa luồng)
• Tiến trình: là chương trình trong thời gian thực hiện (đặt dưới sự quản lý của hệ điều hành). Có sự phân biệt Tiến trình hệ thống (của Hệ điều hành) với Tiến trình người dùng.
Ví dụ: Lớp HCTH102C đang học là một tiến trình
Những ích lợi 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, thì một trong các cô (cô thứ 1) 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 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âu 2: Trình bày nguyên lý tập nguồn và cho ví dụ minh họa
Tập luồng (Thread Pools):
• Tiến trình cha tạo lập sẵn một tập luồng khi khởi động.
• Các luồng trong tập luồng luôn sẵn sàng chờ công việc.
• Khi tiến trình cha (ví dụ Web Server) nhận thêm một yêu cầu, một luồng được đánh thức và đưa vào vận hành.
• Phục vụ xong, luồng được đưa trả về tập luồng.
• Nếu số yêu cầu lớn hơn số luồng trong tập, tiến trình cha chờ đến khi có luồng được giải phóng.
Ví dụ:
Trong một doanh trai quân đội sẽ có một tướng lĩnh (tiến trình cha) và sẽ có một đội binh (tập luồng).
Đội binh này sẽ sẳn sàng chiến đầu khi có mệnh lệnh (sẵn sàng chờ công việc).
Khi có một tên địch đột nhập, Tướng lĩnh sẽ điều binh sĩ 1 (một luồng) đi bắt tên địch (một luồng được đánh thức và đưa vào vận hành).
Trong khi đó, lại có thêm một tên địch khác đột nhập (nhận thêm một yêu cầu), Tướng lĩnh sẽ điều binh sĩ 2 (một luồng) đi bắt địch (một luồng khác được đánh thức và đưa vào vận hành).
Sau khi bắt địch xong, binh sĩ sẽ trở về doanh trại (luồng được trả về tập luồng)
• Tiến trình cha tạo lập sẵn một tập luồng khi khởi động.
• Các luồng trong tập luồng luôn sẵn sàng chờ công việc.
• Khi tiến trình cha (ví dụ Web Server) nhận thêm một yêu cầu, một luồng được đánh thức và đưa vào vận hành.
• Phục vụ xong, luồng được đưa trả về tập luồng.
• Nếu số yêu cầu lớn hơn số luồng trong tập, tiến trình cha chờ đến khi có luồng được giải phóng.
Ví dụ:
Trong một doanh trai quân đội sẽ có một tướng lĩnh (tiến trình cha) và sẽ có một đội binh (tập luồng).
Đội binh này sẽ sẳn sàng chiến đầu khi có mệnh lệnh (sẵn sàng chờ công việc).
Khi có một tên địch đột nhập, Tướng lĩnh sẽ điều binh sĩ 1 (một luồng) đi bắt tên địch (một luồng được đánh thức và đưa vào vận hành).
Trong khi đó, lại có thêm một tên địch khác đột nhập (nhận thêm một yêu cầu), Tướng lĩnh sẽ điều binh sĩ 2 (một luồng) đi bắt địch (một luồng khác được đánh thức và đưa vào vận hành).
Sau khi bắt địch xong, binh sĩ sẽ trở về doanh trại (luồng được trả về tập luồng)
Câu 3: Lập trình đa luồng trong windows
• Windows sử dụng các hàm trong thư viện Win32 API.
• Ứng dụng Windows vận hành như một tiến trình với 1 hoặc nhiều luồng.
• Bài toán Sản xuất-Tiêu thụ có thể được thực thi bằng Ứng dụng đa luồng (Visual C++ 6.0).
• Nhận độ ưu tiên của luồng bằng hàm: int GetThreadPriority (HANDLE threadHandle)
• Thay đổi độ ưu tiên của luồng bằng hàm:BOOL SetThreadPriority (HANDLE threadHandle, int priority)
Với độ ưu tiên priority:
THREAD_PRIORITY_LOWEST ( -2)
THREAD_PRIORITY_BELOW_NORMAL ( -1)
THREAD_PRIORITY_NORMAL ( 0 )
THREAD_PRIORITY_ABOVE_NORMAL (+1)
THREAD_PRIORITY_HIGHEST (+2)
• Có thể lập trình đa luồng với Visual Basic 6.0:
. Sản xuất – Tiêu thụ
. Animations
. Colors
• Ứng dụng Windows vận hành như một tiến trình với 1 hoặc nhiều luồng.
• Bài toán Sản xuất-Tiêu thụ có thể được thực thi bằng Ứng dụng đa luồng (Visual C++ 6.0).
• Nhận độ ưu tiên của luồng bằng hàm: int GetThreadPriority (HANDLE threadHandle)
• Thay đổi độ ưu tiên của luồng bằng hàm:BOOL SetThreadPriority (HANDLE threadHandle, int priority)
Với độ ưu tiên priority:
THREAD_PRIORITY_LOWEST ( -2)
THREAD_PRIORITY_BELOW_NORMAL ( -1)
THREAD_PRIORITY_NORMAL ( 0 )
THREAD_PRIORITY_ABOVE_NORMAL (+1)
THREAD_PRIORITY_HIGHEST (+2)
• Có thể lập trình đa luồng với Visual Basic 6.0:
. Sản xuất – Tiêu thụ
. Animations
. Colors
Trình bày nguyên lý tập luồng (Thread Pool). Nêu vi dụ minh hoạ từ thực tế và đời thường của Thầy.
A.Tập luồng (Thread pool):
Tiến trình cha tạo lập sẵn 1 tập luồng khi khởi động.
Các luồng trong tập luồng luôn sẵn sàng chờ công việc.
Khi tiến trình cha (vd: Web Server) nhận thêm 1 yêu cầu, một luồng được đánh thức và đưa vào vận hành.
Phục vụ xong, luồng được thả 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ẽ điều tiết chờ đến khi có luồng được giải phóng thì giao việc.
B.Ví Dụ:
VD1: Tổng đài Điện thoại (1080) có nhiều Nhân viên trực điện thoại (thì Nhân viên là các luồng con). Số Nhân viên nhiều bao nhiêu tương ứng với số luồng, cùng làm chung 1 văn phòng (chung 1 bộ nhớ), mỗi Nhân viên trực 1 điện thoại (mỗi luồng được điều khiển 1 CPU) do đó luồng có khả năng đáp ứng cao. Khi không có cuộc gọi -> Nhân viên không làm gì (luồng trong trạng thái ngủ). Khi có cuộc gọi đến -> Nhân viên bắt đầu nghe máy (luồng được đánh thức và vận hành) -> kết thúc cuộc gọi ->luồng quay về trạng thái ban đầu.
VD2: Năm 1999, tại Công ty mạng Phương Nam, lúc này Internet chưa phổ biến chỉ có 1 số ứng dụng đơn giản, có 1 ứng dụng hay đó là giới thiệu việc làm qua mạng (và nó làm niềm tự hào của Công ty) được phát triển trên ứng dụng Web CGI (Common Gateway Interface). Có thiết bị hiện đại Server phục vụ 28 user cùng lúc quay số qua modem kết nối tới máy chủ thông qua điện thoại bàn. Nhưng bị 1 lỗi là nếu có 5 người cùng yêu cầu vào trang giới thiệu việc làm 1 lúc, thì hệ thống Web bị treo và cách giải quyết là phải khởi động lại hệ thống. Trong buổi nói chuyện với các chuyên gia (trong đó có Thầy) thì Anh phó Giám đốc nhận định là lỗi phần cứng đề nghị thay. Nhưng Thầy bằng kiến thức suy nghĩ logic Thầy nêu nguyên nhân chính là do khi 5 người dùng yêu cầu chạy ứng dụng thì tạo ra 5 Heavy Process dưới thanh Toolbars, khiến máy Server chứa ứng dụng Web bị treo, vì các nhà lập trình đã sử dụng công nghệ CGI, Thầy đã giải quyết bằng cách làm lại ứng dụng Web bằng ASP (Active Server Pages) và đạt hiệu quả ngay, vì Thầy biết ASP sử dụng công nghệ Đa luồng.
Tiến trình cha tạo lập sẵn 1 tập luồng khi khởi động.
Các luồng trong tập luồng luôn sẵn sàng chờ công việc.
Khi tiến trình cha (vd: Web Server) nhận thêm 1 yêu cầu, một luồng được đánh thức và đưa vào vận hành.
Phục vụ xong, luồng được thả 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ẽ điều tiết chờ đến khi có luồng được giải phóng thì giao việc.
B.Ví Dụ:
VD1: Tổng đài Điện thoại (1080) có nhiều Nhân viên trực điện thoại (thì Nhân viên là các luồng con). Số Nhân viên nhiều bao nhiêu tương ứng với số luồng, cùng làm chung 1 văn phòng (chung 1 bộ nhớ), mỗi Nhân viên trực 1 điện thoại (mỗi luồng được điều khiển 1 CPU) do đó luồng có khả năng đáp ứng cao. Khi không có cuộc gọi -> Nhân viên không làm gì (luồng trong trạng thái ngủ). Khi có cuộc gọi đến -> Nhân viên bắt đầu nghe máy (luồng được đánh thức và vận hành) -> kết thúc cuộc gọi ->luồng quay về trạng thái ban đầu.
VD2: Năm 1999, tại Công ty mạng Phương Nam, lúc này Internet chưa phổ biến chỉ có 1 số ứng dụng đơn giản, có 1 ứng dụng hay đó là giới thiệu việc làm qua mạng (và nó làm niềm tự hào của Công ty) được phát triển trên ứng dụng Web CGI (Common Gateway Interface). Có thiết bị hiện đại Server phục vụ 28 user cùng lúc quay số qua modem kết nối tới máy chủ thông qua điện thoại bàn. Nhưng bị 1 lỗi là nếu có 5 người cùng yêu cầu vào trang giới thiệu việc làm 1 lúc, thì hệ thống Web bị treo và cách giải quyết là phải khởi động lại hệ thống. Trong buổi nói chuyện với các chuyên gia (trong đó có Thầy) thì Anh phó Giám đốc nhận định là lỗi phần cứng đề nghị thay. Nhưng Thầy bằng kiến thức suy nghĩ logic Thầy nêu nguyên nhân chính là do khi 5 người dùng yêu cầu chạy ứng dụng thì tạo ra 5 Heavy Process dưới thanh Toolbars, khiến máy Server chứa ứng dụng Web bị treo, vì các nhà lập trình đã sử dụng công nghệ CGI, Thầy đã giải quyết bằng cách làm lại ứng dụng Web bằng ASP (Active Server Pages) và đạt hiệu quả ngay, vì Thầy biết ASP sử dụng công nghệ Đa luồng.
KhanhChan
- Tổng số bài gửi : 12
Join date : 20/03/2014
-
Sponsored content
-
Trang 1 trong tổng số 3 trang • 1, 2, 3
Trang 1 trong tổng số 3 trang
Permissions in this forum:Bạn không có quyền trả lời bài viết

markdown:
[Thảo luận Bài 5](/t5704-topic)
Trang
**1**trong tổng số **3**trang • [Share](#)• [Trang 1 trong tổng số 3 trang](javascript:Pagination();) • **1**, [2](/t5704p25-topic), [3](/t5704p50-topic) ![ Next](https://illiweb.com/fa/empty.gif)
![ Next](https://illiweb.com/fa/empty.gif)
[Thảo luận Bài 5](/t5704-topic#28242)
Thảo luận những vấn đề liên quan đến Bài 5.
- Attachments
Được sửa bởi Admin ngày 6/4/2014, 08:57; sửa lần 1.
**Admin**
- Admin
- Tổng số bài gửi : 285
Join date : 18/02/2009
[Bài toán Producer/Consumer ](/t5704-topic#28243)
Nhận xét:
• Tổ chức buffer có dạng xoay vòng (circular buffer)
• Producer nhanh hơn: mất dữ liệu
• Consumer nhanh hơn: trùng dữ liệu
Giải quyết:
#define N 100 /* kích thước buffer */
typedef int semaphore; /* kiểu semaphore */
semaphore mutex = 1; /* mutex loại trừ tương hỗ */
semaphore empty = N; /* số phần tử trống */
semaphore full = 0; /* số phần tử có dữ liệu */
void producer(void)
{
int item; /* phần tử dữ liệu */
while (TRUE){
produce_item(&item); /* tạo dữ liệu */
down(&empty); /* giảm số phần tử trống */
down(&mutex); /* vào vùng tranh chấp */
enter_item(item); /* ghi dữ liệu */
up(&mutex); /* rời vùng tranh chấp */
up(&full); /* tăng số phần tử có dữ liệu */
}
}
void consumer(void)
{
int item;
while (TRUE){
down(&full); /* giảm số phần tử có dữ liệu */
down(&mutex); /* vào vùng tranh chấp */
remove_item(&item); /* loại bỏ dữ liệu */
up(&mutex); /* rời vùng tranh chấp */
up(&empty); /* tăng số phần tử trống */
consume_item(item); /* dùng item */
}
}
• Tổ chức buffer có dạng xoay vòng (circular buffer)
• Producer nhanh hơn: mất dữ liệu
• Consumer nhanh hơn: trùng dữ liệu
Giải quyết:
#define N 100 /* kích thước buffer */
typedef int semaphore; /* kiểu semaphore */
semaphore mutex = 1; /* mutex loại trừ tương hỗ */
semaphore empty = N; /* số phần tử trống */
semaphore full = 0; /* số phần tử có dữ liệu */
void producer(void)
{
int item; /* phần tử dữ liệu */
while (TRUE){
produce_item(&item); /* tạo dữ liệu */
down(&empty); /* giảm số phần tử trống */
down(&mutex); /* vào vùng tranh chấp */
enter_item(item); /* ghi dữ liệu */
up(&mutex); /* rời vùng tranh chấp */
up(&full); /* tăng số phần tử có dữ liệu */
}
}
void consumer(void)
{
int item;
while (TRUE){
down(&full); /* giảm số phần tử có dữ liệu */
down(&mutex); /* vào vùng tranh chấp */
remove_item(&item); /* loại bỏ dữ liệu */
up(&mutex); /* rời vùng tranh chấp */
up(&empty); /* tăng số phần tử trống */
consume_item(item); /* dùng item */
}
}
[NguyenVietLong08(HLT3)](/u2027)
- Tổng số bài gửi : 20
Join date : 30/03/2014
[Đa Luồng](/t5704-topic#28245)
Đa luồng là một kỹ thuật cho phép một chương trình hoặc một quá trình để thực hiện nhiều nhiệm vụ đồng thời (cùng một lúc và song song). Nó cho phép một quá trình để chạy các nhiệm vụ của nó trong chế độ song song trên một hệ thống xử lý duy nhất
Trong khái niệm xử lý đa luồng, một số quá trình nhiều nhẹ đang chạy trong một tiến trình / chương trình, nhiệm vụ hoặc một bộ xử lý duy nhất. Ví dụ, bạn sử dụng một trình xử lý, bạn thực hiện nhiều nhiệm vụ khác nhau như in ấn, kiểm tra chính tả và như vậy. Phần mềm đa luồng xử lý mỗi quá trình như là một chương trình riêng biệt.
Trong Java, Java Virtual Machine (JVM) cho phép một ứng dụng có nhiều chủ đề thực hiện chạy đồng thời. Nó cho phép một chương trình có trách nhiệm hơn cho người sử dụng. Khi một chương trình có nhiều chủ đề sau đó CPU có thể chuyển đổi giữa hai chủ đề để thực hiện chúng cùng một lúc.
Ví dụ, nhìn vào sơ đồ hiển thị như sau:
[url=[url=
]
[/url]]Da luong[/url]
Trong sơ đồ này, hai chủ đề đang được thực hiện có nhiều hơn một nhiệm vụ. Nhiệm vụ của mỗi thread được chuyển sang các nhiệm vụ của các chủ đề khác.
Ví dụ nguyên lý tập Luồng
Trong một cửa hàng làm tóc, có rất nhiều nhân viên hớt tóc, làm móng... (tương ứng là các luồng con)
Cứ mỗi người nhân viên, sẽ chịu trách nhiệm phục vụ cho khách hàng của mình (mỗi luồng có thể chạy bởi CPU riêng), do đó có bao nhiêu nhân viên trong tiệm hớt tóc thì sẽ tương ứng với số luồng trong tập luồng
Số lượng luồng càng nhiều khả năng đáp ứng càng cao
Khi có khách hàng đến, thì nhân viên nào đang trống khách (đang ngồi chơi # đang ngủ) thì sẽ phục vụ cho khách hàng ( luồng được nhân yêu cầu, được đánh thức và đưa vào vận hành) khi phục vụ xong nhân viên được tạm nghỉ giải lao chờ có khách hàng mới (luồng trả về tập luồng)
Nếu số lượng khách hàng quá đông, hơn số lượng nhân viên, thì khách hàng sẽ xếp hàng đợi đến khi có 1 nhân viên rảnh (1 luồng được giải phóng)
Trong khái niệm xử lý đa luồng, một số quá trình nhiều nhẹ đang chạy trong một tiến trình / chương trình, nhiệm vụ hoặc một bộ xử lý duy nhất. Ví dụ, bạn sử dụng một trình xử lý, bạn thực hiện nhiều nhiệm vụ khác nhau như in ấn, kiểm tra chính tả và như vậy. Phần mềm đa luồng xử lý mỗi quá trình như là một chương trình riêng biệt.
Trong Java, Java Virtual Machine (JVM) cho phép một ứng dụng có nhiều chủ đề thực hiện chạy đồng thời. Nó cho phép một chương trình có trách nhiệm hơn cho người sử dụng. Khi một chương trình có nhiều chủ đề sau đó CPU có thể chuyển đổi giữa hai chủ đề để thực hiện chúng cùng một lúc.
Ví dụ, nhìn vào sơ đồ hiển thị như sau:
[url=[url=
![ ](http://i62.tinypic.com/wcigjp.gif)
![ ](http://i62.tinypic.com/wcigjp.gif)
Trong sơ đồ này, hai chủ đề đang được thực hiện có nhiều hơn một nhiệm vụ. Nhiệm vụ của mỗi thread được chuyển sang các nhiệm vụ của các chủ đề khác.
Ví dụ nguyên lý tập Luồng
Trong một cửa hàng làm tóc, có rất nhiều nhân viên hớt tóc, làm móng... (tương ứng là các luồng con)
Cứ mỗi người nhân viên, sẽ chịu trách nhiệm phục vụ cho khách hàng của mình (mỗi luồng có thể chạy bởi CPU riêng), do đó có bao nhiêu nhân viên trong tiệm hớt tóc thì sẽ tương ứng với số luồng trong tập luồng
Số lượng luồng càng nhiều khả năng đáp ứng càng cao
Khi có khách hàng đến, thì nhân viên nào đang trống khách (đang ngồi chơi # đang ngủ) thì sẽ phục vụ cho khách hàng ( luồng được nhân yêu cầu, được đánh thức và đưa vào vận hành) khi phục vụ xong nhân viên được tạm nghỉ giải lao chờ có khách hàng mới (luồng trả về tập luồng)
Nếu số lượng khách hàng quá đông, hơn số lượng nhân viên, thì khách hàng sẽ xếp hàng đợi đến khi có 1 nhân viên rảnh (1 luồng được giải phóng)
[Giới Thiệu Một Số Loại Luồng](/t5704-topic#28246)
Luồng Windows 2000
Windows 2000 cài đặt Win32 API. Win32 API là một API chủ yếu cho họ hệ điều hành Windows (Windows 95/98/NT và Windows 2000). Thực vậy, những gì được đề cập trong phần phần này áp dụng tới họ hệ điều hành nàyỨng dụng Windows chạy như một tiến trình riêng rẻ nơi mỗi tiến trình có thể chứa một hay nhiều luồng. Windows 2000 dùng ánh xạ một-một nơi mà mỗi luồng cấp người dùng ánh xạ tới luồng nhân được liên kết tới.Tuy nhiên, Windows cũng cung cấp sự hỗ trợ cho một thư viện có cấu trúc (fiber library) cung cấp chức năng của mô hình nhiều-nhiều. Mỗi luồng thuộc về một tiến trình có thể truy xuất một không gian địa chỉ ảo của tiến trình.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).Tập thanh ghi, ngăn xếp và vùng lưu trữ riêng được xem như ngữ cảnh của luồng và được đặc tả kiến trúc tới phần cứng mà hệ điều hành chạy trên đó. 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 tiến 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)
Luồng Linux
Nhân Linux được giới thiệu trong ấn bản 2.2. Linux cung cấp một lời gọi hệ thống fork với chức năng truyền thống là tạo bản sao một tiến trình . Linux cũng cung cấp lời gọi hệ thống clone mà nó tương tự như tạo một luồng. clone có hành vi rất giống như fork, ngoại trừ thay vì tạo một bản sao của tiến trình gọi, nó tạo một tiến trình riêng chia sẻ không gian địa chỉ của tiến trình gọi. Nó chấm dứt việc chia sẻ không gian địa chỉ của tiến trình cha mà một tác vụ được nhân bản đối xử giống rất nhiều một luồng riêng rẻ.Chia sẻ không gian địa chỉ được cho phép vì việc biểu diễn của một tiến trình trong nhân Linux. Một cấu trúc dữ liệu nhân duy nhất tồn tại cho mỗi tiến trình trong hệ thống. Một cấu trúc dữ liệu nhân duy nhất tồn tại cho mỗi tiến trình trong hệ thống. Tuy nhiên, tốt hơn lưu trữ dữ liệu cho mỗi tiến trình trong cấu trúc dữ liệu là nó chứa các con trỏ chỉ tới các cấu trúc dữ liệu khác nơi dữ liệu này được được lưu. Ví dụ, cấu trúc dữ liệu trên tiến trình chứa các con trỏ chỉ tới các cấu trúc dữ liệu khác hiện diện danh sách tập tin đang mở, thông tin quản lý tín hiệu, và bộ nhớ ảo. Khi fork được gọi, một tiến trình mới được tạo cùng với một bản sao của tất cả cấu trúc dữ liệu của tiến trình cha được liên kết tới. Khi lời gọi hệ thống clone được thực hiện, một tiến trình mới chỉ tới cấu trúc dữ liệu của tiến trình cha, do đó cho phép tiến trình con chia sẻ bộ nhớ và tài nguyên của tiến trình cha. Một tập hợp cờ được truyền như một tham số tới lời gọi hệ thống clone. Tập hợp cờ này được dùng để hiển thị bao nhiêu tiến trình cha được chia sẻ với tiến trình con. Nếu không có cờ nào được đặt, không có chia sẻ xảy ra và clone hoạt động giống như fork. Nếu tất cả năm cờ được đặt, tiến trình con chia sẻ mọi thứ với tiến trình cha. Sự kết hợp khác của cờ cho phép các cấp độ chia sẻ khác nhau giữa hai mức độ cao nhất này. Điều thú vị là Linux không phân biệt giữa tiến trình và luồng. Thật vậy, Linux thường sử dụng thuật ngữ tác vụ-hơn là tiến trình hay luồng-khi tham chiếu tới dòng điều khiển trong chương trình. Ngoài tiến trình được nhân bản, Linux không hỗ trợ đa luồng, cấu trúc dữ liệu riêng hay thủ tục nhân. Tuy nhiên, những cài đặt Pthreads là sẳn dùng cho đa luồng cấp người dùng.
Luồng Java
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.
Windows 2000 cài đặt Win32 API. Win32 API là một API chủ yếu cho họ hệ điều hành Windows (Windows 95/98/NT và Windows 2000). Thực vậy, những gì được đề cập trong phần phần này áp dụng tới họ hệ điều hành nàyỨng dụng Windows chạy như một tiến trình riêng rẻ nơi mỗi tiến trình có thể chứa một hay nhiều luồng. Windows 2000 dùng ánh xạ một-một nơi mà mỗi luồng cấp người dùng ánh xạ tới luồng nhân được liên kết tới.Tuy nhiên, Windows cũng cung cấp sự hỗ trợ cho một thư viện có cấu trúc (fiber library) cung cấp chức năng của mô hình nhiều-nhiều. Mỗi luồng thuộc về một tiến trình có thể truy xuất một không gian địa chỉ ảo của tiến trình.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).Tập thanh ghi, ngăn xếp và vùng lưu trữ riêng được xem như ngữ cảnh của luồng và được đặc tả kiến trúc tới phần cứng mà hệ điều hành chạy trên đó. 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 tiến 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)
Luồng Linux
Nhân Linux được giới thiệu trong ấn bản 2.2. Linux cung cấp một lời gọi hệ thống fork với chức năng truyền thống là tạo bản sao một tiến trình . Linux cũng cung cấp lời gọi hệ thống clone mà nó tương tự như tạo một luồng. clone có hành vi rất giống như fork, ngoại trừ thay vì tạo một bản sao của tiến trình gọi, nó tạo một tiến trình riêng chia sẻ không gian địa chỉ của tiến trình gọi. Nó chấm dứt việc chia sẻ không gian địa chỉ của tiến trình cha mà một tác vụ được nhân bản đối xử giống rất nhiều một luồng riêng rẻ.Chia sẻ không gian địa chỉ được cho phép vì việc biểu diễn của một tiến trình trong nhân Linux. Một cấu trúc dữ liệu nhân duy nhất tồn tại cho mỗi tiến trình trong hệ thống. Một cấu trúc dữ liệu nhân duy nhất tồn tại cho mỗi tiến trình trong hệ thống. Tuy nhiên, tốt hơn lưu trữ dữ liệu cho mỗi tiến trình trong cấu trúc dữ liệu là nó chứa các con trỏ chỉ tới các cấu trúc dữ liệu khác nơi dữ liệu này được được lưu. Ví dụ, cấu trúc dữ liệu trên tiến trình chứa các con trỏ chỉ tới các cấu trúc dữ liệu khác hiện diện danh sách tập tin đang mở, thông tin quản lý tín hiệu, và bộ nhớ ảo. Khi fork được gọi, một tiến trình mới được tạo cùng với một bản sao của tất cả cấu trúc dữ liệu của tiến trình cha được liên kết tới. Khi lời gọi hệ thống clone được thực hiện, một tiến trình mới chỉ tới cấu trúc dữ liệu của tiến trình cha, do đó cho phép tiến trình con chia sẻ bộ nhớ và tài nguyên của tiến trình cha. Một tập hợp cờ được truyền như một tham số tới lời gọi hệ thống clone. Tập hợp cờ này được dùng để hiển thị bao nhiêu tiến trình cha được chia sẻ với tiến trình con. Nếu không có cờ nào được đặt, không có chia sẻ xảy ra và clone hoạt động giống như fork. Nếu tất cả năm cờ được đặt, tiến trình con chia sẻ mọi thứ với tiến trình cha. Sự kết hợp khác của cờ cho phép các cấp độ chia sẻ khác nhau giữa hai mức độ cao nhất này. Điều thú vị là Linux không phân biệt giữa tiến trình và luồng. Thật vậy, Linux thường sử dụng thuật ngữ tác vụ-hơn là tiến trình hay luồng-khi tham chiếu tới dòng điều khiển trong chương trình. Ngoài tiến trình được nhân bản, Linux không hỗ trợ đa luồng, cấu trúc dữ liệu riêng hay thủ tục nhân. Tuy nhiên, những cài đặt Pthreads là sẳn dùng cho đa luồng cấp người dùng.
Luồng Java
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.
[Đa Luồng](/t5704-topic#28248)
đa luồng:
- Mỗi luồng có thể dùng chung và chia sẻ nguồn tài nguyên trong quá trình chạy, nhưng có thể thực hiện một cách độc lập.
- Ứng dụng trách nhiệm có thể được tách
+ Luồng chính chạy giao diện người dung
+ Các luồng phụ nhiệm gửi đến luồng chính.
- Luồng mang tính chất trừu tượng
- Một chương trình đa luồng hoạt động nhanh hơn trên máy tính có cấu hình tốt và mạnh
* Nhược điểm của đa luồng:
- Càng nhiều luồng thì xử lý càng phức tạp
- Cần phát hiện tránh các luồng chết, luồng chạy mà không làm gì trong ứng dụng cảận những vấn đề liên quan đến Bài 5.[/quote]
- Mỗi luồng có thể dùng chung và chia sẻ nguồn tài nguyên trong quá trình chạy, nhưng có thể thực hiện một cách độc lập.
- Ứng dụng trách nhiệm có thể được tách
+ Luồng chính chạy giao diện người dung
+ Các luồng phụ nhiệm gửi đến luồng chính.
- Luồng mang tính chất trừu tượng
- Một chương trình đa luồng hoạt động nhanh hơn trên máy tính có cấu hình tốt và mạnh
* Nhược điểm của đa luồng:
- Càng nhiều luồng thì xử lý càng phức tạp
- Cần phát hiện tránh các luồng chết, luồng chạy mà không làm gì trong ứng dụng cảận những vấn đề liên quan đến Bài 5.[/quote]
[NguyenHuuSonLam(TH10A1)](/u1968)
- Tổng số bài gửi : 35
Join date : 14/03/2014
[Những ích lợi của công nghệ đa luồng](/t5704-topic#28250)
+ Đả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
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
[vothihongngoc72 (HLT3)](/u1971)
- Tổng số bài gửi : 28
Join date : 16/03/2014
[Phân biệt khái niệm luồng và tiến trình, những ích lợi của công nghệ đa luồng](/t5704-topic#28251)
a) Khái niệm luồng ( thread )
+ Luồng 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 của tiến trình truyền thống ( HWP – Heavy Weight Process ).
+ Một luồng là một dòng xử lý cơ bản trong hệ thống. Mỗi luồng xử lý tuần tự đoạn code của nó, sở hữu một con trỏ lệnh, tập các thanh ghi và một vùng nhớ stack riêng-> luồng bao gồm: mã luồng ( thread ID ) + bộ đếm chương trình ( program counter ) + tập thanh ghi ( register set ) + stack.
b) Khái niệm tiến trình ( process)
+ Việc thực hiện các công việc được mô tả thông qua chương trình-> chương trình hoạt động thì chuyển thành tiến trình-> một tiến trình gồm:mã nguồn chương trình (code ) + data + bộ đếm chương trình ( program counter ) + ngăn xếp ( stack ) + giá trị ở các thanh ghi ( register values )-> một tiến trình cần: cung cấp đầy đủ tài nguyên cần thiết + CPU tiếp nhận và thực hiện.
+ Tiến trình có thể có một luồng chính với nhiều luồng phụ.
c) Phân biệt luồng và tiến trình
+ Luồng được coi là mức thấp hơn của tiến trình, mỗi tiến trình có thể có nhiều luồng.
+ Hoạt động của các luồng giống như tiến trình nhưng các luồng cùng chia sẻ không gian địa chỉ chung, còn các tiến trình thì hoàn toàn độc lập.
d) Trình bày những ích lợi của công nghệ đa luồng.
+ Đáp ứng nhanh ( responsiveness ): cho phép luồng chính tiếp tục được thực hiện thậm chí khi một luồng bị ách hoặc quá bận.
+ Chia sẻ tài nguyên ( resource sharing ): các luồng có thể dùng chung bộ nhớ và tài nguyên của luồng cha, cho phép 1 ứng dụng có 1 số luồng khác nhau hoạt động trong cùng 1 không gian địa chỉ.
+ 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 nên việc tạo lập và chuyển ngữ cảnh cũng nhanh hơn.
+ Tận dụng được thế mạnh của kiến trúc đa xử lý ( multiprocessor ): làm tăng tính song song trên hệ máy nhiều CPU ( processor ).
+ Lập trình đa luồng dễ hơn lập trình đa tiến trình, tạo mới 1 tiến trình vừa lâu vừa khó, tạo mới 1 luồng thì nhanh và dễ hơn.
+ Luồng 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 của tiến trình truyền thống ( HWP – Heavy Weight Process ).
+ Một luồng là một dòng xử lý cơ bản trong hệ thống. Mỗi luồng xử lý tuần tự đoạn code của nó, sở hữu một con trỏ lệnh, tập các thanh ghi và một vùng nhớ stack riêng-> luồng bao gồm: mã luồng ( thread ID ) + bộ đếm chương trình ( program counter ) + tập thanh ghi ( register set ) + stack.
b) Khái niệm tiến trình ( process)
+ Việc thực hiện các công việc được mô tả thông qua chương trình-> chương trình hoạt động thì chuyển thành tiến trình-> một tiến trình gồm:mã nguồn chương trình (code ) + data + bộ đếm chương trình ( program counter ) + ngăn xếp ( stack ) + giá trị ở các thanh ghi ( register values )-> một tiến trình cần: cung cấp đầy đủ tài nguyên cần thiết + CPU tiếp nhận và thực hiện.
+ Tiến trình có thể có một luồng chính với nhiều luồng phụ.
c) Phân biệt luồng và tiến trình
+ Luồng được coi là mức thấp hơn của tiến trình, mỗi tiến trình có thể có nhiều luồng.
+ Hoạt động của các luồng giống như tiến trình nhưng các luồng cùng chia sẻ không gian địa chỉ chung, còn các tiến trình thì hoàn toàn độc lập.
d) Trình bày những ích lợi của công nghệ đa luồng.
+ Đáp ứng nhanh ( responsiveness ): cho phép luồng chính tiếp tục được thực hiện thậm chí khi một luồng bị ách hoặc quá bận.
+ Chia sẻ tài nguyên ( resource sharing ): các luồng có thể dùng chung bộ nhớ và tài nguyên của luồng cha, cho phép 1 ứng dụng có 1 số luồng khác nhau hoạt động trong cùng 1 không gian địa chỉ.
+ 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 nên việc tạo lập và chuyển ngữ cảnh cũng nhanh hơn.
+ Tận dụng được thế mạnh của kiến trúc đa xử lý ( multiprocessor ): làm tăng tính song song trên hệ máy nhiều CPU ( processor ).
+ Lập trình đa luồng dễ hơn lập trình đa tiến trình, tạo mới 1 tiến trình vừa lâu vừa khó, tạo mới 1 luồng thì nhanh và dễ hơn.
[vấn đề khi download](/t5704-topic#28255)
sao em không down được bài của thầy
ATTACHMENTS
SanXuatTieuThu C# .NET 2005.zip
You don't have permission to download attachments.
(64 Kb) Downloaded 1 times
ATTACHMENTS
SanXuatTieuThu C# .NET 2005.zip
You don't have permission to download attachments.
(64 Kb) Downloaded 1 times
**Bây giờ được rồi đấy !** __Admin:__
Được sửa bởi NguyễnMinhHoàng45(HLT3) ngày 6/4/2014, 18:34; sửa lần 1.
[Trình bày nguyên lý và ích lợi củacông nghệ đa luồng(Phân biệt tiến trình với luồng, vấn đề chung mã chương trình)](/t5704-topic#28256)
*
- Luồng: 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 hệ thống (HWP - Heavy Weight Process). Mỗi luồng có khả năng chia sẻ tài nguyên với các luồng khác trong 1 tiến trình...
- Tiến trình: là chương trình trong thời gian thực hiện (đặt dưới sự quản lý của hệ điều hành). Có sự phân biệt Tiến trình hệ thống (của Hệ điều hành) với Tiến trình người dùng. Tiến trình có thể có 1 luồng chính với nhiều luồng phụ.
*
- 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ề).
- 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.
- 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).
- 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.
- Lập trình đa luồng dễ hơn lập trình đa tiến trình...
**Phân biệt khái niệm luồng với tiến trình**:
- Luồng: 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 hệ thống (HWP - Heavy Weight Process). Mỗi luồng có khả năng chia sẻ tài nguyên với các luồng khác trong 1 tiến trình...
- Tiến trình: là chương trình trong thời gian thực hiện (đặt dưới sự quản lý của hệ điều hành). Có sự phân biệt Tiến trình hệ thống (của Hệ điều hành) với Tiến trình người dùng. Tiến trình có thể có 1 luồng chính với nhiều luồng phụ.
*
**Những ích lợi 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ề).
- 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.
- 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).
- 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.
- Lập trình đa luồng dễ hơn lập trình đa tiến trình...
[NguyenChiKien(HLT3)](/u2015)
- Tổng số bài gửi : 44
Join date : 23/03/2014
Age : 34
[Re: Thảo luận Bài 5](/t5704-topic#28257)
Em k0 download đc...Admin đã viết:Thảo luận những vấn đề liên quan đến Bài 5.
**Bây giờ được rồi đấy !** __Admin:__ [NguyenChiKien(HLT3)](/u2015)
- Tổng số bài gửi : 44
Join date : 23/03/2014
Age : 34
[cải tiến Producer và Consumer để tránh bị lỗi](/t5704-topic#28258)
hàm Producer và Consumer gốc của thầy
em fix lại như sau, thầy xem thử nhé.
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
- Code:
public void Producer(object id)
{
while(true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.buffer[Program.ptrIn] = NextProduced++;
Program.s[Program.ptrIn] = ((int)id) + 1;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000)); // DateTime.Now.Ticks represents the total number of ticks in local time (not) UTC since the DateTime epoch, which is midnight on January 1st in the year 1AD. (Each tick is 100 nanoseconds; there are 10,000 ticks in a millisecond)
}
}
public void Consumer(object id)
{
while (true)
{
while (Program.ptrIn==Program.ptrOut);
NextConsumed = Program.buffer[Program.ptrOut];
Program.buffer[Program.ptrOut] = -Program.buffer[Program.ptrOut];
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000));
}
}
em fix lại như sau, thầy xem thử nhé.
- Code:
void Produce(object id)
{
while (true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrIn == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrIn - 1;
Program.buffer[pos] = nextProducer++;
Program.producer[pos] = "P" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
void Comsume(object id)
{
while (true)
{
while (Program.ptrIn == Program.ptrOut) ;
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrOut == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrOut - 1;
nextConsumer = Program.buffer[pos];
Program.consumer[pos] = "C" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
__Admin:__
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
[project Produce Consumer](/t5704-topic#28259)
đây là project em tự làm lúc chưa load được code thầy, có gì sai sót thầy chỉ giúp em nhé...
**Tốt lắm !** __Admin:__
- Attachments
[Hệ điều hành đa chương](/t5704-topic#28264)
Hệ điều hành đa chương là hệ điều hành có thể quản lý nhiều chương trình cùng một lúc được nạp vào trong bộ nhớ.
VD:
+ Hệ đa chương: Một người có thể làm nhiều công việc cùng một lúc như: vưa rửa chén, lau nhà, giặt quần áo...
VD:
+ Hệ đa chương: Một người có thể làm nhiều công việc cùng một lúc như: vưa rửa chén, lau nhà, giặt quần áo...
[VoMinhThienHLT3](/u2008)
- Tổng số bài gửi : 9
Join date : 21/03/2014
[SanXuatTieuThu](/t5704-topic#28266)
Thầy ơi! em down không đượcAdmin đã viết:Thảo luận những vấn đề liên quan đến Bài 5.
[dangthituyetnhungTH08a1](/u2002)
- Tổng số bài gửi : 41
Join date : 19/03/2014
[Re: Thảo luận Bài 5](/t5704-topic#28273)
Theo em có nhiều cách để điều khiển thread consumer đồng bộ với producer như đặt biến cờ, cho thread producer điều khiển thread consumer sleep weak up, tạo sự phụ thuộc consumer vào producer...NguyễnMinhHoàng45(HLT3) đã viết:hàm Producer và Consumer gốc của thầy
Em suy nghĩ về code này thì thấy có khả năng nếu 2 thread producer (or consumer) cùng chạy 1 time... thì sẽ dẫn đến cả 2 cái cùng vào đc qua while kiểm tra điều kiện. sau đó P1 ghi dữ liệu rồi tăng biến đếm sau, trong khi ghi dữ liệu thì P2 đã kịp chạy đến và ghi lên ngay sau đó cùng vị trí luôn. sau đó vị trí bị tăng lên 2 do cả 2 thread cùng chạy...
- Code:
public void Producer(object id)
{
while(true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.buffer[Program.ptrIn] = NextProduced++;
Program.s[Program.ptrIn] = ((int)id) + 1;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000)); // DateTime.Now.Ticks represents the total number of ticks in local time (not) UTC since the DateTime epoch, which is midnight on January 1st in the year 1AD. (Each tick is 100 nanoseconds; there are 10,000 ticks in a millisecond)
}
}
public void Consumer(object id)
{
while (true)
{
while (Program.ptrIn==Program.ptrOut);
NextConsumed = Program.buffer[Program.ptrOut];
Program.buffer[Program.ptrOut] = -Program.buffer[Program.ptrOut];
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000));
}
}
em fix lại như sau, thầy xem thử nhé.
- Code:
void Produce(object id)
{
while (true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrIn == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrIn - 1;
Program.buffer[pos] = nextProducer++;
Program.producer[pos] = "P" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
void Comsume(object id)
{
while (true)
{
while (Program.ptrIn == Program.ptrOut) ;
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrOut == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrOut - 1;
nextConsumer = Program.buffer[pos];
Program.consumer[pos] = "C" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
Admin:
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
[PhanVietTrung(HLT3)](/u1960)
- Tổng số bài gửi : 25
Join date : 09/03/2014
[Re: Thảo luận Bài 5](/t5704-topic#28274)
mỉnh thấy bạn hiểu sai vấn đề 1 chút. mình không cần đồng bộ giữa producer và consumer mà giữa chính producer với nhau, cũng như các consumer với nhau,vì 2 loại này hoạt động độc lập với nhau, nếu bạn tạo sự phụ thuộc là sai tinh thần thuật toán. có thể dùng 2 biến cờ để cùng lúc chỉ chạy 1 thread producer (consumer) nhưng mà dẫn đến 1 lúc chỉ có 1 cái làm... nếu như process lâu dẫn đến phải chờ cho xong mới đến lượt thread khác.PhanVietTrung(HLT3) đã viết:Theo em có nhiều cách để điều khiển thread consumer đồng bộ với producer như đặt biến cờ, cho thread producer điều khiển thread consumer sleep weak up, tạo sự phụ thuộc consumer vào producer...NguyễnMinhHoàng45(HLT3) đã viết:hàm Producer và Consumer gốc của thầy
Em suy nghĩ về code này thì thấy có khả năng nếu 2 thread producer (or consumer) cùng chạy 1 time... thì sẽ dẫn đến cả 2 cái cùng vào đc qua while kiểm tra điều kiện. sau đó P1 ghi dữ liệu rồi tăng biến đếm sau, trong khi ghi dữ liệu thì P2 đã kịp chạy đến và ghi lên ngay sau đó cùng vị trí luôn. sau đó vị trí bị tăng lên 2 do cả 2 thread cùng chạy...
- Code:
public void Producer(object id)
{
while(true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.buffer[Program.ptrIn] = NextProduced++;
Program.s[Program.ptrIn] = ((int)id) + 1;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000)); // DateTime.Now.Ticks represents the total number of ticks in local time (not) UTC since the DateTime epoch, which is midnight on January 1st in the year 1AD. (Each tick is 100 nanoseconds; there are 10,000 ticks in a millisecond)
}
}
public void Consumer(object id)
{
while (true)
{
while (Program.ptrIn==Program.ptrOut);
NextConsumed = Program.buffer[Program.ptrOut];
Program.buffer[Program.ptrOut] = -Program.buffer[Program.ptrOut];
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000));
}
}
em fix lại như sau, thầy xem thử nhé.
- Code:
void Produce(object id)
{
while (true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrIn == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrIn - 1;
Program.buffer[pos] = nextProducer++;
Program.producer[pos] = "P" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
void Comsume(object id)
{
while (true)
{
while (Program.ptrIn == Program.ptrOut) ;
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrOut == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrOut - 1;
nextConsumer = Program.buffer[pos];
Program.consumer[pos] = "C" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
Admin:
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
[Re: Thảo luận Bài 5](/t5704-topic#28275)
NguyễnMinhHoàng45(HLT3) đã viết:mỉnh thấy bạn hiểu sai vấn đề 1 chút. mình không cần đồng bộ giữa producer và consumer mà giữa chính producer với nhau, cũng như các consumer với nhau,vì 2 loại này hoạt động độc lập với nhau, nếu bạn tạo sự phụ thuộc là sai tinh thần thuật toán. có thể dùng 2 biến cờ để cùng lúc chỉ chạy 1 thread producer (consumer) nhưng mà dẫn đến 1 lúc chỉ có 1 cái làm... nếu như process lâu dẫn đến phải chờ cho xong mới đến lượt thread khác.PhanVietTrung(HLT3) đã viết:Theo em có nhiều cách để điều khiển thread consumer đồng bộ với producer như đặt biến cờ, cho thread producer điều khiển thread consumer sleep weak up, tạo sự phụ thuộc consumer vào producer...NguyễnMinhHoàng45(HLT3) đã viết:hàm Producer và Consumer gốc của thầy
Em suy nghĩ về code này thì thấy có khả năng nếu 2 thread producer (or consumer) cùng chạy 1 time... thì sẽ dẫn đến cả 2 cái cùng vào đc qua while kiểm tra điều kiện. sau đó P1 ghi dữ liệu rồi tăng biến đếm sau, trong khi ghi dữ liệu thì P2 đã kịp chạy đến và ghi lên ngay sau đó cùng vị trí luôn. sau đó vị trí bị tăng lên 2 do cả 2 thread cùng chạy...
- Code:
public void Producer(object id)
{
while(true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.buffer[Program.ptrIn] = NextProduced++;
Program.s[Program.ptrIn] = ((int)id) + 1;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000)); // DateTime.Now.Ticks represents the total number of ticks in local time (not) UTC since the DateTime epoch, which is midnight on January 1st in the year 1AD. (Each tick is 100 nanoseconds; there are 10,000 ticks in a millisecond)
}
}
public void Consumer(object id)
{
while (true)
{
while (Program.ptrIn==Program.ptrOut);
NextConsumed = Program.buffer[Program.ptrOut];
Program.buffer[Program.ptrOut] = -Program.buffer[Program.ptrOut];
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
Thread.Sleep((int)(DateTime.Now.Ticks % 5000));
}
}
em fix lại như sau, thầy xem thử nhé.
- Code:
void Produce(object id)
{
while (true)
{
while ((Program.ptrIn + 1) % Program.BUFFER_SIZE == Program.ptrOut) ;
Program.ptrIn = (Program.ptrIn + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrIn == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrIn - 1;
Program.buffer[pos] = nextProducer++;
Program.producer[pos] = "P" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
void Comsume(object id)
{
while (true)
{
while (Program.ptrIn == Program.ptrOut) ;
Program.ptrOut = (Program.ptrOut + 1) % Program.BUFFER_SIZE;
int pos;
if (Program.ptrOut == 0)
pos = Program.BUFFER_SIZE - 1;
else
pos = Program.ptrOut - 1;
nextConsumer = Program.buffer[pos];
Program.consumer[pos] = "C" + id.ToString();
Thread.Sleep((int) (DateTime.Now.Ticks % 5000));
}
}
Admin:
- Em chỉ ra nhược điểm của Giải pháp kiểm tra biểu thức trên các con trỏ In-Out (dùng chung sửa chung bởi nhiều luồng một lúc) để xác định trạng thái Đầy/Có sản phẩm của Buffer, là Đúng !
- Tạm thời ta làm như vậy, và về cơ bản chấp nhận được, nhưng Không chắc chắn !
- Sang Bài 7 sẽ học về Phương tiện đồng bộ hoá để giải quyết triệt để vấn đề này !
Bạn còn nhớ ví dụ tập luồng chứ, thread có thể khởi tạo sẵn nhưng chưa chắc phải chạy ngay lúc nó khởi tạo, do đó ta có thể gọi nó khi nào cần thôi, tùy trường hợp sử dụng như thế nào mà chúng ta cần nó đồng bộ hay không, mình nghĩ bạn hiểu sai giữa đồng bộ, bất đồng bộ, xử lý song song và xử lý tuần tự.
[PhanVietTrung(HLT3)](/u1960)
- Tổng số bài gửi : 25
Join date : 09/03/2014
[Re: Thảo luận Bài 5](/t5704-topic#28276)
Nói như bạn trên thì khi cần Suppend Producer lại hoặc Suppend Consumer lại sẽ như thế nào, khi 1 cái chạy ảnh hưởng đến cái kia, cứ wake cái kia dậy???
[Re: Thảo luận Bài 5](/t5704-topic#28277)
vả lại, mình và thầy đang trao đổi vì sự bất đồng bộ dữ liệu khi có 2 tiến trình Producer cùng chạy cùng lúc sẽ dẫn đến ghi dữ liệu sai vi trí (do vị trí chưa kịp cập nhật) bạn nhé... còn chuyện bạn nói là thuộc về thuật giải... có thể tiết kiệm tài nguyên bằng cách cho ngủ luồng Consumer khi Producer chưa sản xuất sau đó Producer sản xuất xong thì đánh thức dậy lấy... nó ảnh hưởng đến nguyên lý chung bài toán là Consumer và Producer độc lập với nhau không phụ thuộc nhau. Bạn có thể thấy điều này khi mà Consumer trước khi lấy phải kiểm tra còn hàng trong buffer không? nếu như cách bạn thì không cần kiểm tra. nếu như producer làm xong gọi consumer dậy lấy thì đó là cơ chế đút ăn bạn nhé...
[Re: Thảo luận Bài 5](/t5704-topic#28279)
Tóm tắt bài 5
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ể.
**Ưu điểm và nhược điểm của một ứng dụng Multithreaded**
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ể.
[lekhacduyanh03(HLT3)](/u1948)
- Tổng số bài gửi : 12
Join date : 15/04/2013
Age : 26
[Giới thiệu về lập trình Multithread trong C#](/t5704-topic#28280)
MultiThread, hiểu đơn giản là tạo 1 chương trình sao cho có hơn 1 luồng dữ liệu được xử lý trong đó. Ta thấy ở thời điểm hiện nay ngành công nghệ phần cứng đang phát triển mạnh mẽ, máy tính và các thiết bị di động được trang bị các bộ xử lý đa nhân để có thể làm được cùng một lúc nhiều công việc hơn – Xử lý song song. Việc phát triển chương trình chạy đa luồng cũng có ý nghĩa rất lớn bên ngành mạng viễn thông, giúp tăng tốc và cải thiện đường truyền tín hiệu.
Mình xin giới thiệu các bạn lập trình Thread trong C#.
Ta tạo ra 3 instances của lớp Thread và cho chúng start (để bắt đầu chạy), nhưng ta chỉ start 2 thread t1 và t2, nên ta sẽ thấy được chúng được in ra màn hình xen kẽ nhau, sau khi t1 và t2 kết thúc thì t3 bắt đầu được thực thi, mình xin giải thích sử dụng phương thức Join bên dưới.
using System;
using System.Threading;
namespace MultithreadDemo
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(a));
Thread t2 = new Thread(new ThreadStart(b));
Thread t3 = new Thread(new ThreadStart(c));
t1.Start();
t2.Start();
t1.Join();
t2.Join();
t3.Start();
Console.Read();
}
private static void c()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread c");
}
}
private static void b()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread b");
}
}
private static void a()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread a");
}
}
}
}
Join là một phương thức rất hay dùng khi xử lý Thread. Ta có thể hiểu ý nghĩa có phương thức này như sau: Khi một Thread gọi phương thức Join thì Thread đó sẽ được ưu tiên trong hệ thống. Những lện nào nằm sau phương thức Joinn chỉ được thực thi khi Thread kết thúc. Những lệnh đã chạy từ trước thì vẫn được thực thi với Thread hiện tại, và không có ảnh hưởng gì.
Mình xin giới thiệu các bạn lập trình Thread trong C#.
Ta tạo ra 3 instances của lớp Thread và cho chúng start (để bắt đầu chạy), nhưng ta chỉ start 2 thread t1 và t2, nên ta sẽ thấy được chúng được in ra màn hình xen kẽ nhau, sau khi t1 và t2 kết thúc thì t3 bắt đầu được thực thi, mình xin giải thích sử dụng phương thức Join bên dưới.
using System;
using System.Threading;
namespace MultithreadDemo
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(a));
Thread t2 = new Thread(new ThreadStart(b));
Thread t3 = new Thread(new ThreadStart(c));
t1.Start();
t2.Start();
t1.Join();
t2.Join();
t3.Start();
Console.Read();
}
private static void c()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread c");
}
}
private static void b()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread b");
}
}
private static void a()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("thread a");
}
}
}
}
Join là một phương thức rất hay dùng khi xử lý Thread. Ta có thể hiểu ý nghĩa có phương thức này như sau: Khi một Thread gọi phương thức Join thì Thread đó sẽ được ưu tiên trong hệ thống. Những lện nào nằm sau phương thức Joinn chỉ được thực thi khi Thread kết thúc. Những lệnh đã chạy từ trước thì vẫn được thực thi với Thread hiện tại, và không có ảnh hưởng gì.
[NguyenTrungTruc(HLT3)](/u1955)
- Tổng số bài gửi : 17
Join date : 09/03/2014
[Phân biệt khái niện luồng với tiến trình. Và trình bày những lợi ích của công nghệ đa luồng](/t5704-topic#28281) **Phân biệt khái niệm luồng với tiến trình**
• Luồng: 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 hệ thống (HWP – Heavy Weight Process)
Ví dụ: Lớp học là một tiến trình. Trong lớp sẽ có một giáo viên(đơn luồng) và các học viên (đa luồng)
• Tiến trình: là chương trình trong thời gian thực hiện (đặt dưới sự quản lý của hệ điều hành). Có sự phân biệt Tiến trình hệ thống (của Hệ điều hành) với Tiến trình người dùng.
Ví dụ: Lớp HCTH102C đang học là một tiến trình
Những ích lợi 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, thì một trong các cô (cô thứ 1) 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 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âu 2: Trình bày nguyên lý tập nguồn và cho ví dụ minh họa](/t5704-topic#28282) **Tập luồng (Thread Pools):**
• Tiến trình cha tạo lập sẵn một tập luồng khi khởi động.
• Các luồng trong tập luồng luôn sẵn sàng chờ công việc.
• Khi tiến trình cha (ví dụ Web Server) nhận thêm một yêu cầu, một luồng được đánh thức và đưa vào vận hành.
• Phục vụ xong, luồng được đưa trả về tập luồng.
• Nếu số yêu cầu lớn hơn số luồng trong tập, tiến trình cha chờ đến khi có luồng được giải phóng.
**Ví dụ:**
Trong một doanh trai quân đội sẽ có một tướng lĩnh (tiến trình cha) và sẽ có một đội binh (tập luồng).
Đội binh này sẽ sẳn sàng chiến đầu khi có mệnh lệnh (sẵn sàng chờ công việc).
Khi có một tên địch đột nhập, Tướng lĩnh sẽ điều binh sĩ 1 (một luồng) đi bắt tên địch (một luồng được đánh thức và đưa vào vận hành).
Trong khi đó, lại có thêm một tên địch khác đột nhập (nhận thêm một yêu cầu), Tướng lĩnh sẽ điều binh sĩ 2 (một luồng) đi bắt địch (một luồng khác được đánh thức và đưa vào vận hành).
Sau khi bắt địch xong, binh sĩ sẽ trở về doanh trại (luồng được trả về tập luồng)
[Câu 3: Lập trình đa luồng trong windows](/t5704-topic#28283)
• Windows sử dụng các hàm trong thư viện Win32 API.
• Ứng dụng Windows vận hành như một tiến trình với 1 hoặc nhiều luồng.
• Bài toán Sản xuất-Tiêu thụ có thể được thực thi bằng Ứng dụng đa luồng (Visual C++ 6.0).
• Nhận độ ưu tiên của luồng bằng hàm: int GetThreadPriority (HANDLE threadHandle)
• Thay đổi độ ưu tiên của luồng bằng hàm:BOOL SetThreadPriority (HANDLE threadHandle, int priority)
Với độ ưu tiên priority:
THREAD_PRIORITY_LOWEST ( -2)
THREAD_PRIORITY_BELOW_NORMAL ( -1)
THREAD_PRIORITY_NORMAL ( 0 )
THREAD_PRIORITY_ABOVE_NORMAL (+1)
THREAD_PRIORITY_HIGHEST (+2)
• Có thể lập trình đa luồng với Visual Basic 6.0:
. Sản xuất – Tiêu thụ
. Animations
. Colors
• Ứng dụng Windows vận hành như một tiến trình với 1 hoặc nhiều luồng.
• Bài toán Sản xuất-Tiêu thụ có thể được thực thi bằng Ứng dụng đa luồng (Visual C++ 6.0).
• Nhận độ ưu tiên của luồng bằng hàm: int GetThreadPriority (HANDLE threadHandle)
• Thay đổi độ ưu tiên của luồng bằng hàm:BOOL SetThreadPriority (HANDLE threadHandle, int priority)
Với độ ưu tiên priority:
THREAD_PRIORITY_LOWEST ( -2)
THREAD_PRIORITY_BELOW_NORMAL ( -1)
THREAD_PRIORITY_NORMAL ( 0 )
THREAD_PRIORITY_ABOVE_NORMAL (+1)
THREAD_PRIORITY_HIGHEST (+2)
• Có thể lập trình đa luồng với Visual Basic 6.0:
. Sản xuất – Tiêu thụ
. Animations
. Colors
[Trình bày nguyên lý tập luồng (Thread Pool). Nêu vi dụ minh hoạ từ thực tế và đời thường của Thầy.](/t5704-topic#28286)
A.Tập luồng (Thread pool):
Tiến trình cha tạo lập sẵn 1 tập luồng khi khởi động.
Các luồng trong tập luồng luôn sẵn sàng chờ công việc.
Khi tiến trình cha (vd: Web Server) nhận thêm 1 yêu cầu, một luồng được đánh thức và đưa vào vận hành.
Phục vụ xong, luồng được thả 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ẽ điều tiết chờ đến khi có luồng được giải phóng thì giao việc.
B.Ví Dụ:
VD1: Tổng đài Điện thoại (1080) có nhiều Nhân viên trực điện thoại (thì Nhân viên là các luồng con). Số Nhân viên nhiều bao nhiêu tương ứng với số luồng, cùng làm chung 1 văn phòng (chung 1 bộ nhớ), mỗi Nhân viên trực 1 điện thoại (mỗi luồng được điều khiển 1 CPU) do đó luồng có khả năng đáp ứng cao. Khi không có cuộc gọi -> Nhân viên không làm gì (luồng trong trạng thái ngủ). Khi có cuộc gọi đến -> Nhân viên bắt đầu nghe máy (luồng được đánh thức và vận hành) -> kết thúc cuộc gọi ->luồng quay về trạng thái ban đầu.
VD2: Năm 1999, tại Công ty mạng Phương Nam, lúc này Internet chưa phổ biến chỉ có 1 số ứng dụng đơn giản, có 1 ứng dụng hay đó là giới thiệu việc làm qua mạng (và nó làm niềm tự hào của Công ty) được phát triển trên ứng dụng Web CGI (Common Gateway Interface). Có thiết bị hiện đại Server phục vụ 28 user cùng lúc quay số qua modem kết nối tới máy chủ thông qua điện thoại bàn. Nhưng bị 1 lỗi là nếu có 5 người cùng yêu cầu vào trang giới thiệu việc làm 1 lúc, thì hệ thống Web bị treo và cách giải quyết là phải khởi động lại hệ thống. Trong buổi nói chuyện với các chuyên gia (trong đó có Thầy) thì Anh phó Giám đốc nhận định là lỗi phần cứng đề nghị thay. Nhưng Thầy bằng kiến thức suy nghĩ logic Thầy nêu nguyên nhân chính là do khi 5 người dùng yêu cầu chạy ứng dụng thì tạo ra 5 Heavy Process dưới thanh Toolbars, khiến máy Server chứa ứng dụng Web bị treo, vì các nhà lập trình đã sử dụng công nghệ CGI, Thầy đã giải quyết bằng cách làm lại ứng dụng Web bằng ASP (Active Server Pages) và đạt hiệu quả ngay, vì Thầy biết ASP sử dụng công nghệ Đa luồng.
Tiến trình cha tạo lập sẵn 1 tập luồng khi khởi động.
Các luồng trong tập luồng luôn sẵn sàng chờ công việc.
Khi tiến trình cha (vd: Web Server) nhận thêm 1 yêu cầu, một luồng được đánh thức và đưa vào vận hành.
Phục vụ xong, luồng được thả 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ẽ điều tiết chờ đến khi có luồng được giải phóng thì giao việc.
B.Ví Dụ:
VD1: Tổng đài Điện thoại (1080) có nhiều Nhân viên trực điện thoại (thì Nhân viên là các luồng con). Số Nhân viên nhiều bao nhiêu tương ứng với số luồng, cùng làm chung 1 văn phòng (chung 1 bộ nhớ), mỗi Nhân viên trực 1 điện thoại (mỗi luồng được điều khiển 1 CPU) do đó luồng có khả năng đáp ứng cao. Khi không có cuộc gọi -> Nhân viên không làm gì (luồng trong trạng thái ngủ). Khi có cuộc gọi đến -> Nhân viên bắt đầu nghe máy (luồng được đánh thức và vận hành) -> kết thúc cuộc gọi ->luồng quay về trạng thái ban đầu.
VD2: Năm 1999, tại Công ty mạng Phương Nam, lúc này Internet chưa phổ biến chỉ có 1 số ứng dụng đơn giản, có 1 ứng dụng hay đó là giới thiệu việc làm qua mạng (và nó làm niềm tự hào của Công ty) được phát triển trên ứng dụng Web CGI (Common Gateway Interface). Có thiết bị hiện đại Server phục vụ 28 user cùng lúc quay số qua modem kết nối tới máy chủ thông qua điện thoại bàn. Nhưng bị 1 lỗi là nếu có 5 người cùng yêu cầu vào trang giới thiệu việc làm 1 lúc, thì hệ thống Web bị treo và cách giải quyết là phải khởi động lại hệ thống. Trong buổi nói chuyện với các chuyên gia (trong đó có Thầy) thì Anh phó Giám đốc nhận định là lỗi phần cứng đề nghị thay. Nhưng Thầy bằng kiến thức suy nghĩ logic Thầy nêu nguyên nhân chính là do khi 5 người dùng yêu cầu chạy ứng dụng thì tạo ra 5 Heavy Process dưới thanh Toolbars, khiến máy Server chứa ứng dụng Web bị treo, vì các nhà lập trình đã sử dụng công nghệ CGI, Thầy đã giải quyết bằng cách làm lại ứng dụng Web bằng ASP (Active Server Pages) và đạt hiệu quả ngay, vì Thầy biết ASP sử dụng công nghệ Đa luồng.
[KhanhChan](/u2005)
- Tổng số bài gửi : 12
Join date : 20/03/2014
**Sponsored content**
-
[Trang 1 trong tổng số 3 trang](javascript:Pagination();) • **1**, [2](/t5704p25-topic), [3](/t5704p50-topic) ![ Next](https://illiweb.com/fa/empty.gif)
![ Next](https://illiweb.com/fa/empty.gif)
Trang
**1**trong tổng số **3**trang
Bạn
**Permissions in this forum:** **không có quyền**trả lời bài viết

X-XSS-Protection: 1; mode=block

X-Content-Type-Options: nosniff

Vary: User-Agent

P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"