Hệ Điều HànhCơ Chế Liên Lạc Tiến Trình Tiến trình là thể hiện (instance) của một chương trình máy tính trong bộ nhớ, đang thực thi hoặc chờ thực thi.Một chương trình có thể có vài tiến trình trong bộ nhớMột tiến trình gồm:Mã nguồn chương trình (code)Dữ liệu (data)Bộ đếm chương trình (program counter)Ngăn xếp (stack)Giá trị ở các thanh ghi (register values)Các tiến trình muốn trao đổi dữ liệu với nhau cần sử dụng các cơ chế giao tiếp tiến trình
Trang 1Giảng Viên: L……….
Trang 2 Nhóm …:
……….
……….
……….
……….
……….
Trang 3 Chủ đề:
1 Các cơ chế liên lạc của tiến trình
Sinh viên thực hiện :
• ……….(Vùng nhớ chia sẻ, Trao đổi thông điệp, Sockets)
• ………(Vùng nhớ chia sẻ, Đường ống)
• ………(Tín hiệu, Trao đổi thông điệp)
2 Xây dựng ứng dụng quản lí máy tính
Sinh viên thực hiện:
• ………
• ………
Trang 4 Tiến trình là thể hiện (instance) của một chương trình máy tính trong bộ nhớ, đang thực thi hoặc chờ thực thi.
Một chương trình có thể có vài tiến trình trong bộ nhớ
• Giá trị ở các thanh ghi (register values)
Các tiến trình muốn trao đổi dữ liệu với nhau cần sử dụng các cơ chế giao tiếp tiến trình
Tiến Trình:
Trang 5Các cơ chế liên lạc
Vùng nhớ chia sẻ
Vùng nhớ chia sẻ
Trao đổi thông điệp
Trao đổi thông điệp
Trang 61.0 Signal(Tín Hiệu):
Khái niệm :
Tín hiệu là một cơ chế phần mềm tương tự như các ngắt cứng tác động đến các tiến trình
Một tín hiệu được sử dụng để thông báo cho tiến trình về một sự kiện nào đó xảy ra
Có nhiều tín hiệu được định nghĩa, mỗi một tín hiệu có một ý nghĩa tương ứng với một sự kiện đặc trưng
Ví dụ: Một số tín hiệu của UNIX
SIGINT Người dùng nhấn phím DEL để ngắt xử lý tiến trình
SIGILL Tiến trình xử lí một chỉ thị bất hợp lệ
Trang 71.0 Signal(Tín Hiệu):
Mỗi tiến trình sở hữu một bảng biễu diễn các tín hiệu khác nhau
Với mỗi tín hiệu sẽ có tương ứng một trình xử lý tín hiệu (signal handler) qui định các xử lý của tiến trình khi nhận được tín hiệu tương ứng.
Liên lạc bằng tín hiệu mang tính chất không đồng bộ, nghĩa là một tiến trình nhận tín hiệu không thể xác định trước thời điểm nhận tính hiệu
Các tiến trình không thể kiểm tra được sự kiện tương ứng với tín hiệu có thật sự xảy ra.
Các tiến trình chỉ có thể thông báo cho nhau về một biến cố nào đó, mà không trao đổi dữ liệu theo cơ chế này được
Trang 82.0 Pipe( Đường ống):
Đường ống là cách để đưa đầu ra của một chương trình thành dữ liệu đầu vào của một chương trình khác mà không cần qua một file trung gian.
Đường ống thực chất là một vùng bộ nhớ tạm thời, nơi lưu trữ đầu ra của một lệnh và sau đó chuyển chúng cho đầu vào của lệnh thứ hai
• Lệnh_1 | Lệnh_2
• ls | sort
• ls | sort | less
Trang 92.0 Pipe( Đường ống):
Định hướng lại các thiết bị đầu vào/ra chuẩn :
Hầu hết tất cả các lệnh hiển thị kết quả đầu ra ra màn hình, và lấy dữ liệu đầu vào từ bàn phím
Có thể gửi kết quả đầu ra ra file cũng như đọc đầu vào từ file bằng cách sử dụng định hướng lại (redirect)
Ghi kết quả của 1 lệnh ra 1 file (thay vì màn hình)
Lệnh > tên_file_đầu_ra
ls > danh_sach_file
Định hướng đầu vào: Lệnh < tên_file_đầu_vào
cat < a.txt
sort < a.txt > a.sorted.txt
tr “[a-z]” “[A-Z]” < a.txt > b.txt
Trang 10Có hai loại Pipe:
Unnamed Pipe: chỉ giới hạn trong không gian phạm vi địa chỉ của một quá trình, cho phép giao tiếp giữa quá trình cha với các quá trình con
hay giữa các quá trình con của một quá trình với nhau Trong đó các quá trình con được thay thế bởi các luồng
Named pipe (còn gọi là FIFO): loại này cho phép hai quá trình có không gian địa chỉ khác nhau (trên cung một máy) giao tiếp với nhau Thực
chất nó giống như một tập tin với quy định rằng dữ liệu sẽ được lấy ra ở đầu tập tin và thêm vào ở cuối tập tin
2.0 Pipe( Đường ống):
Trang 112.0 Pipe( Đường ống):
Đường ống Pipe giao tiếp trao đổi dữ liệu một chiều:
Hàm pipe() dùng để tạo đường ống có khả năng đọc/ghi
#include <unistd.h>
int pipe ( int filedes[2])
Phần tử thứ nhất của mảng được dùng để đọc trong khi phần tử thứ hai được dùng để ghi
Tương đương với việc sử dụng hai đường ống một chiều
Cả hai tiến trình cha và con đều có thể đọc và ghi dữ liệu vào đường ống
Trang 122.0 Pipe( Đường ống):
Tuy nhiên cũng rất dễ gây ra tình trạng tắc nghẽn
Hàm read() đọc dữ liệu từ Pipe
Hàm write() dùng để ghi dữ liệu vào trong đường ống
Cơ chế : nếu đường ống rỗng hàm sẽ khóa trong trạng thái chờ (block) cho đến khi dữ liệu được đổ vào đường ống hay khi đường ống bị đóng lại bởi phía bên ghi
Trang 133.0 Shared Memory(Vùng nhớ chia sẻ):
Giới thiệu: Cách tiếp cận của cơ chế này là cho nhiều tiến trình cùng truy xuất đến một vùng nhớ
chung gọi là vùng nhớ chia sẻ(shared memory).
Dữ liệu chỉ đơn giản được đặt vào một vùng nhớ mà nhiều tiến trình có thể cùng truy cập được.
Các tiến trình chia sẻ một vùng nhớ vật lý thông qua trung gian không gian địa chỉ của chúng.
Trang 14 Vùng nhớ chia sẻ :
Một phần không gian nhớ không thuộc sở hữu của tiến trình nào
Được HĐH tạo ra
Các tiến trình có thể ánh xạ địa chỉ vào không gian chia sẻ này để truy xuất dữ liệu (như đối với không gian nội bộ)
Dữ liệu được đặt vào một vùng đệm (buffer) được dùng để chia sẻ dữ liệu giữa các tiến trình:
Kích thước không giới hạn (unbounded buffer): tiến trình đọc có thể chờ, tiến trình ghi không bao giờ chờ.
Kích thước có giới hạn (bounded buffer): cả tiến trình đọc và ghi có thể chờ
3.0 Shared Memory(Vùng nhớ chia sẻ):
Trang 15Ưu Điểm Nhược Điểm
Không giới hạn số lượng tiến trình, chiều trao đổi, và thứ
tự truy cập
Nhanh, đơn giản để trao đổi dữ liệu giữa các tiến trình
Khó bảo đảm sự toàn vẹn dữ liệu
Không thể áp dụng hiệu quả trong hệ phân tán
Nhận xét :
3.0 Shared Memory(Vùng nhớ chia sẻ):
Trang 16 Giới thiệu: Hệ điều hành cung cấp một cơ chế liên lạc giữa các tiến trình thông qua việc gửi thông điệp
Để hỗ trợ cơ chế liên lạc bằng thông điệp, hệ điều hành cung cấp các hàm IPC chuẩn (Interprocess communication), cơ bản là hai hàm:
Send(message) : gửi một thông điệp
Receive(message) : nhận một thông điệp
4.0 Message Passing(Trao đổi thông điệp):
Giao tiếp giữa các tiến trình không cần dùng bộ nhớ chia sẻ
⇒hữu ích trong môi trường phân tán, giao tiếp qua mạng
Trang 174.0 Message Passing(Trao đổi thông điệp):
Truyền thông điệp:
Tiến trình P và Q muốn giao tiếp với nhau:
Tạo một nối kết giao tiếp (communication link)
Trao đổi thông điệp thông qua send/receive
Kết thúc trao đổi liên kết giao tiếp bị hủy bỏ
Phương thức cài đặt nối kết giao tiếp:
Giao tiếp trực tiếp hay gián tiếp
Đồng bộ hay bất đồng bộ
Kích thước thông điệp cố định hay biến đổi
Trang 184.1 Giao tiếp trực tiếp(Direct Communication):
Các quá trình phải được đặt tên rõ ràng:
Send(P, msg): gởi thông điệp tới quá trình P
Receive(Q, msg): nhận thông điệp từ quá trình Q
Các thuộc tính của nối kết giao tiếp:
Các nối kết được thiết lập tự động
Một nối kết kết hợp với chính xác một cặp quá trình
Giữa mỗi cặp quá trình tồn tại chính xác một nối kết
Nối kết có thể một hướng, nhưng thường là hai hướng
Trang 194.2 Giao tiếp gián tiếp(Indirect Communication):
Các thông điệp được gửi và nhận thông qua mailbox hay port
Mỗi mailbox có một định danh (id) duy nhất
Các quá trình chỉ có thể giao tiếp nếu chúng dùng chung mailbox
• Send (A, msg): gửi thông điệp tới hộp thư A
• Receive(A, msg):nhận thông điệp từ hộp thư A
Các thuộc tính của nối kết gián tiếp:
Nối kết chỉ được thiết lập nếu các quá trình chia sẻ cùng 1 hộp thư
Một nối kết có thể kết hợp với nhiều quá trình.
Mỗi cặp tiến trình có thể dùng chung nhiều nối kết giao tiếp.
Nối kết có thể một hướng hay hai hướng.
Trang 204.2 Giao tiếp gián tiếp(Indirect Communication):
Các tác vụ cơ bản trong giao tiếp gián tiếp:
Tạo mailbox mới
Gửi và nhận thông điệp qua mailbox
Xóa mailbox
Chia sẻ mailbox:
Các tiến trình có thể chia sẻ cùng 1 mailbox
⇒Vấn đề: nếu 1 tiến trình gửi thì tiến trình nào sẽ nhận?
Giải pháp:
• Một liên kết chỉ tương ứng với 2 tiến trình
• Chỉ cho phép 1 tiến trình thực hiện thao tác nhận tại 1 thời điểm
• HĐH chỉ định tiến trình nhận (1 tiến trình), và thông báo cho tiến trinh gửi biết người nhận
Trang 214.3 Đồng bộ hóa (Synchronisation)
Giao tiếp giữa hai quá trình xảy ra bởi lời gọi hàm cơ sở send và receive.
Truyền thông điệp có thể chặn (blocking) hay không chặn (non-blocking)
(cũng được xem như đồng bộ và bất đồng bộ.)
Blocking được xem là đồng bộ (synchronous):
Blocking send: tiến trình gửi chờ cho đến khi thông điệp được nhận.
Blocking receive : tiến trình nhận chờ cho đến khi thông điệp sẵn sàng
Non-blocking được xem là bất đồng bộ (asynchronous):
Non-blocking send: gửi thông điệp và tiếp tục thực hiện công việc khác.
Non-blocking receive: nhận một thông điệp hay rỗng.
Trang 224.4 Vùng đệm (buffering)
Dù giao tiếp có thể là trực tiếp hay gián tiếp, các thông điệp trao đổi giữa các tiến trình được lưu trong hàng đợi tạm thời
Về cơ bản, một hàng đợi như thế có thể được cài đặt theo ba cách:
Sức chứa không giới hạn
Hàng đợi có chiều dài tối đa là 0; Do đó,
liên kết không thể có bất kỳ thông điệp
nào chờ trong nó
Hàng đợi có chiều dài giới hạn n; Do đó, nhiều nhất n thông điệp có thể thường trú trong nó Tiến trình gửi bị chặn khi
vùng đệm bị đầy
Hàng đợi có chiều dài không giới hạn; Do đó
số lượng thông điệp bất
kỳ có thể chờ trong nó Tiến trình gửi không
bao giờ bị chặn.
Trang 235.0 Sockets:
Socket là một giao diện lập trình ứng dụng mạng.
Lập trình socket là cách lập trình cho phép chúng ta kết nối các máy tính truyền tải
và nhận dữ liệu từ máy tính thông qua mạng
Socket cho phép thiết lập các kênh giao tiếp mà hai đầu kênh được đánh dấu bởi hai cổng (port) Thông qua các cổng này một quá
trình có thể nhận và gửi dữ liệu với các quá trình khác
Trang 255.0 Sockets:
So sánh sự khác biệt giữa hai chế độ giao tiếp TCP - UDP
• Tồn tại kênh giao tiếp ảo giữa hai bên giao tiếp.
• Dữ liệu được gởi đi theo chế độ bảo đảm: có kiểm tra lỗi truyền lại gói tin
lỗi hay mất, bảo đảm thứ tự đến của các gói tin
• Dữ liệu chính xác, Tốc độ truyền chậm.
• Không tồn tại kênh giao tiếp ảo giữa hai bên giao tiếp
• Dữ liệu được gởi đi theo chế độ không bảo đảm: Không kiểm tra lỗi, không phát hiện không truyền lại gói tin bị lỗi hay mất, không bảo đảm thứ tự đến của các gói tin
• Dữ liệu không chính xác, tốc độ truyền nhanh.
• Thích hợp cho các ứng dụng cần tốc độ, không cần chính xác cao: truyền
âm thanh, hình ảnh
Trang 265.1 UDP Socket:
Socket phi kết nối UDP cho phép gửi các thông điệp mà không cần phải thiết lập kết nối trước.
Một phương thức đọc sẽ đọc toàn bộ thông điệp được gửi bởi một phương thức gửi
Tuy nhiên, giao thức UDP không đảm bảo dữ liệu được truyền tới đích.
Chương trinh phía Server:
Tạo một Socket
Liên kết với 1 IPEndPoint cục bộ
Gửi nhận dữ liệu theo giao thức đã thiết kế
Trang 275.1 UDP Socket:
Mô hình ứng dụng Client – Server :
UDP Client UDP Server
Recvfrom()
Sento()
Bind()Sento()
Socket() Socket()
Close()Close()
Recvfrom()
data(request) data(reply)
Server yêu cầu tạo socket
Server yêu cầu gán số hiệu cổng cho socket
Client yêu cầu tạo socket
Trao đổi thông tin giữa
Client và Server
Trang 285.1 UDP Socket:
Ví dụ minh họa giao thức UDP: Chương trình gửi và nhận thông điệp
// tạo một đối tượng MyUdpClient và lắng nghe port 2008
UdpClient udp = new UdpClient(2008);
// thực hiện nghe liên tục
while (true)
{
//xác định điểm Remote IP
IPEndPoint RemoteIPEndPoint = new IPEndPoint (IPAddress.Any, 0);
// thu lấy thông tin từ client dạng byte
Byte[] data = udp.Receive(ref RemoteIPEndPoint);
// tạo một UDP Object và kết nối với máy chủ
UdpClient udp = new UdpClient();
udp.Connect(_host, _port);
// khai báo isConnect kiểu bool là true
bool isConnect = true;
Trang 29Kích thước dữ liệu nhỏ và trình tự không quan trọng
Không gửi các dữ liệu quan trọng
Không cần truyền lại các gói tin
Băng thông của mạng tốt
5.1 UDP Socket:
1 2 3 4
UDP
Socket
UDP
Socket
Trang 305.2 TCP Socket:
Giao thức TCP là giao thức truyền tin hướng liên kết có thể sử dụng truyền tin với độ tin cậy cao
Khi được chạy, server cần được xác định rõ địa chỉ IP và sẽ “lắng nghe” trên một port cụ thể
Server sẽ nằm trong trạng thái này cho đến khi Client gửi đến một yêu cầu kết nối.
Sau khi được server chấp nhận, một connection sẽ hình thành cho phép server và client giao tiếp với nhau.
Trang 31 Socket(): Server yêu cầu tạo một Socket
Bind(): Server yêu cầu gắn số hiệu port cho Socket
Listen(): Server lắng nghe các yêu cầu kết nối từ các Client trên cổng đã được gán
Server sẵn sàng phục vụ Client
Trang 325.2 TCP Socket:
listen()
socket()bind()
Socket(): Client yêu cầu tạo một Socket
Connect(): Client gửi yêu cầu kết nối đến Server có địa chỉ IP và port
xác định
Accept(): Server chấp nhận kết nối của Client, kênh giao tiếp ảo được
hình thành, Client và Server có thể truyền thông tin với nhau
Trang 335.2 TCP Socket:
Server Client
write() read()
accept() write()
read()
request
reply
Sau khi chấp nhận yêu cầu kết nối, Server thực hiện lệnh Read() và
chờ cho đến khi có thông điệp yêu cầu từ Client
Server phân tích và thực thi yêu cầu Kết quả sẽ trả về Client bằng
lệnh Wrire()
Sau khi gửi yêu cầu bằng lệnh Write(), Client chờ nhận thông điệp kết quả từ Server bằng lệnh Read()
Trang 345.2 TCP Socket:
Server Client
write() read()
accept() write() request
Trang 355.2 TCP Socket:
listen()
socket()bind()
reply
read()
close() close()
Trang 365.2 TCP Socket:
Chương trình phía Server:
Tạo một Socket
Gắn Socket với một địa chỉ cụ thể (binding)
Đặt Socket ở trạng thái lắng nghe kết nối tới từ Client
Trang 375.2 TCP Socket:
Gửi và nhận thông điệp dạng Byte[ ]
Lớp NetworkStream và Socket cung cấp các phương thức gửi và nhận dữ liệu dạng mảng byte.
Vì vậy cần phải thực hiện các bước chuyển đổi dữ liệu sang dạng byte và ngược lại
Ví dụ: Chương trình gửi nhận dữ liệu sử dụng TCPListener, Socket (phía server) và TCPClient, NetworkStream (phía client) dạng mảng byte
Ở đây ta sử dụng dữ liệu dạng văn bản ASCII trong console, và dùng các lớp trong namespace System.Text để chuyển đổi bằng cách tạo đối tượng có kiểu ASCIIEncoding
Trang 385.2 TCP Socket:
private const int BUFFER_SIZE=1024;
private const int PORT_NUMBER=9540;
static ASCIIEncoding encoding=new ASCIIEncoding();
public static void Main() {
try {
IPAddress address = IPAddress.Parse(" 127.0.0.1 ");
TcpListener listener =newTcpListener(address,PORT_NUMBER);
// listen
listener.Start();
Console.WriteLine(“ TCPServer started on “ + listener.LocalEndpoint);
Console.WriteLine(" Waiting for a connection ");
Console.WriteLine(" Error: " + ex);
} Console.Read();
Server.cs
Trang 395.2 TCP Socket:
Client.cs
private const int BUFFER_SIZE=1024;
private const int PORT_NUMBER=9540;
static ASCIIEncoding encoding= new ASCIIEncoding();
public static void Main() {
try {
TcpClient client = new TcpClient();
//connect
client.Connect(“ 127.0.0.1 ",PORT_NUMBER);
Stream stream = client.GetStream();
Console.WriteLine(" Connected to TCPServer ");
Console.Write(“ Enter a username: ");
Console.WriteLine(" Error: " + ex);
} Console.Read();
Trang 405.2 TCP Socket:
Chạy Server trước, cửa sổ console của Server sẽ hiển thị:
Sau đó chạy Client, nếu kết nối thành công, Server sẽ hiển thị:
Trang 415.2 TCP Socket:
Chuyển qua cửa sổ console của Client và nhập username Nếu nhận được dữ liệu, server sẽ gửi trả lại message: “Hello [UserName]”
Ngay sau bước này, cả server và client đều thực hiện đóng kết nối.
Trang 425.2 TCP Socket:
Gửi và nhận thông điệp dạng StreamReader và StreamWriter
StreamReader: Được sử dụng để đọc các ký tự từ một stream
StreamWriter: Được sử dụng để ghi các ký tự tới một stream
Các đối tượng StreamReader và StreamWriter có thể được khởi tạo trực tiếp từ NetworkStream
Ví dụ: chương trình gửi và nhận thông điệp dạng StreamReader và StreamWriter
Sử dụng vòng lặp while để thực hiện gửi nhận dữ liệu liên tục giữa server/client
Nếu chuỗi nhập vào là EXIT thì dừng chương trình