✨Đèn báo (lập trình)

Đèn báo (lập trình)

Trong khoa học máy tính, đèn báo là một biến được bảo vệ hoặc một kiểu dữ liệu trừu tượng tạo ra sự trừu tượng hoá đơn giản nhưng hữu dụng để kiểm soát truy cập của nhiều tiến trình đến một tài nguyên chung trong môi trường lập trình song song.

Một cách nhìn về đèn báo là một bản ghi có bao nhiêu đơn vị của một tài nguyên có thể sử dụng, gắn với các tác vụ điều chỉnh bản ghi đó một cách an toàn (nghĩa là không tạo ra race condition) khi yêu cầu hoặc giải phóng các đơn vị và đợi đến khi một đơn vị rảnh rỗi nếu cần. Đèn báo là một công cụ hữu ích để chống race condition và khoá chết, tuy nhiên việc sử dụng nó không đảm bảo rằng chương trình không gặp phải các vấn đề trên. Đèn báo cho phép một số lượng tuỳ ý tài nguyên gọi là đèn báo đếm (counting semaphore) trong khi đèn báo bị giới hạn trong giá trị 0 và 1 được gọi là đèn báo nhị phân (binary semaphores).

Khái niệm đèn báo được phát minh bởi nhà nghiên cứu người Hà Lan Edsger Dijkstra.

Ý nghĩa và cài đặt

Đèn báo đếm được trang bị hai thao tác, ký hiệu là VP. Thao tác V tăng đèn báo S và thao tác P giảm nó. Ý nghĩa của chúng được giải thích bên dưới. Ngoặc vuông chỉ ra các thao tác nguyên tử, nghĩa là các thao tác không thể chia nhỏ dưới góc nhìn của các tiến trình khác.

function V(semaphore S): Atomically increment S [S ← S + 1]

function P(semaphore S): repeat: Between repetitions of the loop other processes may operate on the semaphore [if S > 0: Atomically decrement S - note that S cannot become negative S ← S - 1 break]

Giá trị của đèn báo S là số đơn vị của tài nguyên còn rỗi. Thao tác P chờ đợi tích cực hoặc ngủ cho đến khi tài nguyên được bảo vệ trở nên rảnh rỗi, khi đó nó ngay lập tức yêu cầu. Thao tác V ngược lại: làm cho tài nguyên rảnh rỗi trở lại sau khi một tiến trình đã sử dụng xong.

Ví dụ: Bài toán người sản xuất/người tiêu dùng

Cho emptyCountfullCount là các đèn báo đém, và emptyCount được khởi tạo bằng N trong khi fullCount bằng 0, người sản xuất thực hiện lặp lại công việc sau:

produce: P(emptyCount) putItemIntoQueue(item) V(fullCount)

Người sử dụng lặp đi lặp lại công việc sau:

consume: P(fullCount) item ← getItemFromQueue() V(emptyCount)

Lưu ý rằng thứ tự các phép toán là quan trọng. Ví dụ, nếu người sản xuất đặt hàng vào hàng đợi sau khi tăng fullCount, người sử dụng có thể cố lấy hàng trước khi nó được ghi. Nếu người sản xuất đặt hàng vào trước khi giảm emptyCount, nó có thể vượt quá giới hạn của hàng đợi.

Nguồn gốc tên hàm

Các tên chuẩn PV xuất phát từ chữ cái đầu của từ tiếng Hà Lan. V là viết tắt của verhogen ("tăng lên"). Có nhiều giải thích cho P, bao gồm proberen - "kiểm tra", passeer - "vượt qua", probeer - "thử", and pakken for "bắt". Tuy nhiên, Dijkstra viết rằng ông định sử dụng từ ghép prolaag, viết tắt cho probeer te verlagen, nghĩa là "thử giảm",

Trong ALGOL 68, nhân Linux, và một số sách giáo khoa tiếng Anh, các thao tác P and V thường được gọi lần lượt là downup. Trong thực hành, chúng thường được gọi là waitsignal, acquirerelease (thư viên chuẩn của Java sử dụng cách này), hoặc pendpost. Một vài cuốn sách sử dụng procurevacate để phù hợp với viết tắt ban đầu bằng tiếng Hà Lan.

Đèn báo và mutex

Mutex về căn bản giống như đèn báo nhị phân và đôi khi sử dụng cùng một cách cài đặt. Tuy nhiên khái niệm "mutex" thường được sử dụng để mô tả một cấu trúc ngăn cản hai tiến trình cũng thực hiện một đoạn mã hoặc truy cập một dữ liệu cùng lúc. Khái niệm đèn báo nhị phân thường mô tả cấu trúc dùng để hạn chế truy cập vào một tài nguyên.

Trong nhiều trường hợp một mutex có khái niệm "chủ": duy nhất tiến trình khoá mutex được quyền mở nó. Ngược lại đèn báo nói chung không đặt ra ràng buộc này, điều mà ví dụ người sản xuất - người tiêu dùng ở trên dựa vào.

Sử dụng

Đèn báo được nhiều hệ điều hành cung cấp như là một mẫu đồng bộ hoá và được sử dụng ở nhiều nơi. Tuy nhiên xu hướng phát triển các ngôn ngữ lập trình là các cách đồng bộ hoá có cấu trúc hơn, như là monitor. Những sự trừu tượng hoá này thường chứa đèn báo hoặc mutex bên trong những không thể hiện giao diện của đèn báo ra đối với lập trình viên. Xu hướng này được khuyến khích mở những vấn đề nghiêm trọng và khó chẩn đoán khi đèn báo bị sử dụng không đúng cách, một nguy cơ được giảm thiểu rất nhiều khi sự đồng bộ hoá được gắn chặt với tài nguyên mà nó điều khiển một cách tự động bởi ngôn ngữ thay vì bằng tay bởi người lập trình.

👁️ 1 | 🔗 | 💖 | ✨ | 🌍 | ⌚
Trong khoa học máy tính, **đèn báo** là một biến được bảo vệ hoặc một kiểu dữ liệu trừu tượng tạo ra sự trừu tượng hoá đơn giản nhưng hữu dụng để kiểm soát truy
**Lập trình máy tính** hay **lập chương trình máy tính,** thường gọi tắt là **lập trình** (, hay _programming_), là việc lập ra chương trình làm việc cho máy có bộ xử lý, nói riêng
Bộ sách bao gồm 1. Tớ Đến Với Lập Trình Tập Làm Game 2. Tớ Đến Với Lập Trình Tập Làm Phim Hoạt Hình 3. Tớ Đến Với Lập Trình Tập Thu Âm Và Lồng
**Pascal** là một ngôn ngữ lập trình cho máy tính thuộc dạng mệnh lệnh và thủ tục, được Niklaus Wirth phát triển vào năm 1970. Pascal là ngôn ngữ lập trình đặc biệt thích hợp
phải|nhỏ|402x402px|[[Mã nguồn của một chương trình máy tính đơn giản được viết bằng ngôn ngữ lập trình C. Khi được biên dịch và chạy, nó sẽ cho kết quả "Hello, world!".]] **Ngôn ngữ lập trình**
**Lập trình hướng đối tượng** () là một mẫu hình lập trình dựa trên khái niệm "đối tượng", mà trong đó, đối tượng chứa đựng các dữ liệu trong các trường, thường được gọi là
**C** là một ngôn ngữ mệnh lệnh được phát triển từ đầu thập niên 1970 bởi Dennis Ritchie để dùng trong hệ điều hành UNIX. Từ đó, ngôn ngữ này đã lan rộng ra nhiều
**Python** () là ngôn ngữ lập trình bậc cao đa năng. Triết lý thiết kế của nó nhấn mạnh khả năng đọc mã bằng cách sử dụng thụt lề đáng kể. Python có kiểu động
**C#** (**C Sharp**, đọc là _"xi-sáp"_) là một ngôn ngữ lập trình hướng đối tượng đa năng, mạnh mẽ được phát triển bởi Microsoft, C# là phần khởi đầu cho kế hoạch .NET của họ.
**Java** (phiên âm Tiếng Việt: "_Gia-va_") là một ngôn ngữ lập trình hướng đối tượng, dựa trên lớp được thiết kế để có càng ít phụ thuộc thực thi càng tốt. Nó là ngôn ngữ
thumb|**[[Phép tính lambda** là một hệ thống hình thức để định nghĩa hàm, ứng dụng hàm và đệ quy được Alonzo Church đề xuất vào những năm 193x.]] **Lý thuyết ngôn ngữ lập trình** (thường
thumb|Các vòng lặp lên kế hoạch và phản hồi trong lập trình cực hạn **Lập trình cực hạn** (tiếng Anh: **Extreme programming**, viết tắt là **XP**) là một quy trình phát triển phần mềm nhằm
**Ruby** là một ngôn ngữ lập trình hướng đối tượng, có khả năng phản ứng. Theo tác giả, Ruby chịu ảnh hưởng bởi Perl, Smalltalk, Eiffel, Ada và Lisp. Ruby cung cấp nhiều mẫu hình
nhỏ|300x300px| [[Petr Mitrichev (trái) và Gennady Korotkevich (phải), hai lập trình viên thi đấu nổi tiếng trong một cuộc thi.]] **Lập trình thi đấu** () là một môn thể thao trí tuệ trong đó những
Trong ngành khoa học máy tính, **lập trình hàm** (**lập trình chức năng**) là một mô hình lập trình xem việc tính toán là sự đánh giá các hàm toán học và tránh sử dụng
**Kotlin** là một ngôn ngữ lập trình kiểu tĩnh chạy trên máy ảo Java (JVM) và có thể được biên dịch sang mã nguồn Java hay sử dụng cơ sở hạ tầng trình biên dịch
Trong lập trình hướng đối tượng, **lớp** (**class**) là một chương trình-mã-khuôn mẫu có thể mở rộng được để tạo các đối tượng, cung cấp giá trị khởi tạo cho trạng thái (biến thành viên)
nhỏ|Cbmain Trong khoa học máy tính, một **ngôn ngữ lập trình bậc cao** (tiếng Anh: _high-level programming language_) là một ngôn ngữ lập trình có sự trừu tượng hóa mạnh mẽ khỏi các chi tiết
nhỏ|Ảnh chụp màn hình tài liệu [[API web viết bởi NASA]] Một **giao diện lập trình ứng dụng** (, viết tắt: _API_) là một giao diện mà một hệ thống máy tính hay ứng dụng
Trong khoa học máy tính, **bao đóng** (closure) là một hàm hay một tham chiếu tới một hàm cùng với môi trường tham chiếu - một bảng chứa tham chiếu đến mỗi biến không phải
**Giao tiếp lập trình ứng dụng mở** (Open API) (thường được gọi là một giao tiếp lập trình ứng dụng công cộng.) là một giao tiếp lập trình ứng dụng công khai cung cấp cho
Trong lập trình máy tính, một **triển khai của ngôn ngữ lập trình** là một hệ thống để thực thi chương trình máy tính. Có hai cách tiếp cận chung để triển khai một ngôn
Trong khoa học máy tính, **ngôn ngữ lập trình bậc thấp** là một ngôn ngữ lập trình liên quan chặt chẽ đến phần cứng máy tính. Từ "thấp" không có nghĩa là ngôn ngữ này
Programming Paradigm hay **Phương thức lập trình** là một kiểu cơ bản của lập trình vi tính (Computer Programming). Paragigm với các khái niệm và sự trừu tượng dùng trong mô tả các thành phần
nhỏ **Trò chơi lập trình** (tiếng Anh: _Programming game_) là một trò chơi máy tính mà người chơi không có ảnh hưởng trực tiếp vào tiến trình của game. Thay vào đó, một chương trình
**Swift** là một ngôn ngữ lập trình hướng đối tượng dành cho việc phát triển iOS và macOS, watchOS, tvOS và z/OS. được giới thiệu bởi Apple tại hội nghị WWDC 2014. Swift được mong
Trong điện toán, **lập trình hướng khía cạnh** (tiếng Anh: _aspect-oriented programming_, viết tắt: _AOP_) là một mẫu hình lập trình nhằm tăng tính mô đun bằng cách cho phép phân tách những mối quan
**Scratch** là một ngôn ngữ lập trình mang tính giáo dục miễn phí dựa trên các khối ngôn ngữ lập trình trực quan (VPL) và trang web chủ yếu để giáo dục lập trình, với
**Lập trình logic hàm** (tiếng Anh: **functional logic programming**) là sự kết hợp mẫu hình lập trình chức năng và lập trình logic thành một ngôn ngữ lập trình duy nhất. Phong cách lập trình
Trong lập trình hướng đối tượng dựa trên lớp, **hàm tạo** (tiếng Anh: _constructor_, viết tắt: _ctor_) trong một lớp là một kiểu chương trình con đặc biệt được dùng để tạo ra đối tượng.
**Batch** là một ngôn ngữ lập trình được dựa trên các tập tin thực thi batch (*.bat, *.cmd,...) để chạy. Chúng sẽ được thực thi dưới dạng một cửa sổ **Command Prompt** để chạy những
**Dylan** là một ngôn ngữ lập trình đa mẫu hình có hỗ trợ hàm, lập trình hướng đối tượng (OOP), động và phục hồi trong khi cung cấp một mô hình lập trình được thiết
Trong điện toán, **lập trình phản ứng** (tiếng Anh: **reactive programming**) là một mẫu hình lập trình khai báo liên quan đến các luồng dữ liệu và lan truyền của sự thay đổi. Với mẫu
**R** là một ngôn ngữ lập trình và môi trường phần mềm dành cho tính toán và đồ họa thống kê. Đây là một bản hiện thực ngôn ngữ lập trình S với ngữ nghĩa
**Ngôn ngữ lập trình hệ thống** (tiếng Anh: _system programming language_) thường đề cập đến một ngôn ngữ lập trình được dùng cho lập trình hệ thống; các ngôn ngữ đó được thiết kế để
**CLU** là một ngôn ngữ lập trình được tạo ra ở Viện Công nghệ Massachusetts (MIT) bởi Barbara Liskov và các sinh viên của bà trong khoảng thời gian từ 1974 đến 1975. Mặc dù
Rust là một ngôn ngữ lập trình đa mô hình, cấp cao, có mục đích chung. Rust có sự tập trung vào tăng cường hiệu suất, đảm bảo an toàn kiểu và khả năng xử
thumb|Minh họa mã nguồn [[Java (programming language)|Java với comment **mở đầu** được biểu thị bằng màu **đỏ** và comment **nội dòng** bằng màu **lục**. **Mã chương trình** là bằng màu **lam**.]]Trong lập
**Quảng cáo lập trình** () là một quy trình tự động trong việc mua và bán các vị trí quảng cáo theo thời gian thực trên nền tảng kỹ thuật số và là một phần
Trong trí tuệ nhân tạo, **lập trình di truyền** (_genetic programming, GP_) là một kỹ thuật tiến hóa các chương trình mà ban đầu chưa thích nghi (thường là chương trình ngẫu nhiên) cho đến
Ngôn ngữ lập trình C có một hệ thống mở rộng cho việc **khai báo các biến của các kiểu khác nhau**. Những quy tắc dành cho các kiểu phức tạp có thể gây nhầm
phải|Sơ đồ về chu kỳ tế bào, cho thấy trạng thái của [[nhiễm sắc thể trong mỗi giai đoạn của chu kỳ.]] **Chu kỳ tế bào**, hay **chu kỳ phân bào**, là một vòng tuần
phải|Biểu đồ hoạt động của một trình biên dịch lý tưởng. **Trình biên dịch** () hay **phần mềm biên dịch** là một chương trình máy tính làm công việc dịch một chuỗi các câu lệnh
nhỏ| Chương trình máy tính "Xin chào, thế giới" của [[Brian Kernighan (1978) ]] **Chương trình máy tính** là tập hợp các câu lệnh thực hiện một tác vụ cụ thể khi được máy tính
**Điện Đô vương Trịnh Cán** (chữ Hán: 奠都王鄭檊, 1775 – 17 tháng 12, 1782) là vị chúa Trịnh thứ 9 của vương tộc Trịnh cầm quyền ở miền Bắc Đại Việt thời nhà Lê trung
**Bộ trình dịch GNU** ( - thường được viết tắt thành **GCC**) là một tập hợp các trình biên dịch được thiết kế cho nhiều ngôn ngữ lập trình khác nhau. GCC là một thành
nhỏ|phải|A [[Graphical user interface|GUI Chương trình "Hello World", viết bằng ngôn ngữ Perl]] nhỏ|phải|Có thể thực thi dòng mã ở máy điện tử cầm tay [[PlayStation Portable homebrew|PlayStation Portable Sony.]] nhỏ|phải|Thử máy [[CNC ở Perspex]]
Trong khoa học máy tính, **chương trình con **(subprogram) hay **subroutine** là một đoạn chương trình được đóng gói thành một đơn vị trình, nó thực hiện một số tác vụ cụ thể mà chương
**Gecko** là một bộ máy trình bày được phát triển bởi Mozilla. Nó được sử dụng trong trình duyệt Firefox, email client Thunderbird và nhiều dự án khác Gecko được thiết kế để hỗ trợ
Bộ sách học lập trình với Scratch 3 từ cơ bản đến nâng cao và lập trình App Inventor bao gồm Combo tài liệu học lập trình với Scratch 3 gồm 3 cuốn Sách Lập