Các nhóm hàm
Các hàm liên quan đến hệ thống được chia thành 2
nhóm dựa vào cách chúng được thực thi:
Hàm thư viện: là hàm bình thường đặt trong thư viện bên
ngoài chương trình. Các tham số được đặt trong các
thanh ghi của CPU hoặc trên stack. Sự thực hiện được
truyền đến đoạn mã đầu của hàm (thường trong thư viện
chia sẻ được nạp)
System call: được thực thi trong Linux kernel. Các tham
số được chuyển đến và xử lý trong kernel đến khi lời gọi
kết thúc.
Linux cung cấp khoảng 200 system call. Một số được
sử dụng cho chính hệ thống, số còn lại được sử
dụng chỉ trong việc thực thi các hàm thư viện đặc biệt
Liệt kê trong /usr/include/asm/unistd.h
Hầu hết các system call được khai báo trong
21 trang |
Chia sẻ: candy98 | Lượt xem: 822 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Bài giảng Nguyên lý Hệ điều hành - Chương 6: Linux System Calls - Phạm Quang Dũng, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Chương 6. Linux System Calls
Phạm Quang Dũng
2Các nhóm hàm
Các hàm liên quan đến hệ thống được chia thành 2
nhóm dựa vào cách chúng được thực thi:
Hàm thư viện: là hàm bình thường đặt trong thư viện bên
ngoài chương trình. Các tham số được đặt trong các
thanh ghi của CPU hoặc trên stack. Sự thực hiện được
truyền đến đoạn mã đầu của hàm (thường trong thư viện
chia sẻ được nạp)
System call: được thực thi trong Linux kernel. Các tham
số được chuyển đến và xử lý trong kernel đến khi lời gọi
kết thúc.
3 Linux cung cấp khoảng 200 system call. Một số được
sử dụng cho chính hệ thống, số còn lại được sử
dụng chỉ trong việc thực thi các hàm thư viện đặc biệt
Liệt kê trong /usr/include/asm/unistd.h
Hầu hết các system call được khai báo trong
46.1. Sử dụng strace
Lệnh strace theo dõi sự thực hiện của một chương
trình khác, liệt kê bất cứ system call nào chương
trình gọi và bất kỳ signal nào nó nhận được.
% strace tên_CT [các_tham_số]
Vd: % strace hostname
56.2. access: kiểm tra quyền truy nhập file
system call access xác định xem tiến trình gọi có
quyền truy nhập file hay không.
access(ts1, ts2)
ts1: đường dẫn tới file
ts2: chuỗi bit hoặc F_OK, R_OK, W_OK, X_OK
Giá trị trả về:
= 0 nếu tiến trình có các quyền trong ts2
= -1 nếu có lỗi, mã lỗi được thiết lập thích hợp là
ENOENT (file không tồn tại)
EACCES (không có quyền tới file hoặc thư mục chứa file)
EROFS (khi yêu cầu ghi lên file có thuộc tính chỉ đọc)
6Chương trình ví dụ
Listing 8.1 (check-access.c): kiểm tra sự tồn tại của
file, xác định quyền đọc và ghi.
Cách chạy:
% ./check-access /cpr/test.c
76.3. fsync, fdatasync: flushing disk buffer
Trên hầu hết HĐH, khi bạn ghi 1 file, dữ liệu không lập tức
được ghi lên đĩa. HĐH lưu dữ liệu đó trong 1 buffer để:
giảm số lần ghi đĩa
cải thiện sự đáp ứng của chương trình
Khi buffer đầy hoặc trạng thái nào đó xuất hiện (vd: khi
hết lượng thời gian ấn định), HĐH ghi các dữ liệu trong
buffer lên đĩa luôn một lần.
Khi mất nguồn đột ngột, dữ liệu trong buffer bị mất
Với chương trình quan trọng, yêu cầu dữ liệu phải được
ghi lên đĩa ngay lập tức.
Dùng fsync(writable_file_descriptor)
8fsync, fdatasync (tiếp)
Listing 8.3 (write_journal_entry.c): ghi từng mục đơn
dòng lên 1 file nhật ký.
Có thể mở file để thực hiện vào-ra đồng bộ: tất cả
các lần ghi được chuyển đến đĩa ngay lập tức:
xác định cờ O_SYNC khi mở file.
96.4. getrlimit, setrlimit: giới hạn tài nguyên
cho phép tiến trình đọc và thiết lập giới hạn tài
nguyên hệ thống mà nó có thể sử dụng.
mỗi hàm có 2 tham số:
ts1: mã xác định loại giới hạn tài nguyên:
RLIMIT_CPU: lượng thời gian tối đa mà chương trình
thực sự được sử dụng CPU (giây)
RLIMIT_DATA: dung lượng bộ nhớ tối đa cho CT
RMIT_NPROC: số tối đa tiến trình con được chạy
RMIT_NOFILE: số tối đa file descriptor mà tiến trình có
thể mở tại một thời điểm.
ts2: con trỏ tới biến structrlimit.
10
Chương trình ví dụ
Listing 8.4 (limit-cpu.c): thiết lập giới hạn thời gian
CPU là 1 giây rồi bước vào vòng lặp vô hạn. Linux sẽ
giết tiến trình ngay khi nó dùng CPU vượt 1 giây.
Khi chạy CT:
% ./limit-cpu
CPU time limit exceeded
11
6.5. mprotect: thiết lập quyền bộ nhớ
Chương 5, phần “Mapped Memory” đã nói cách sử dụng
system call mmap
Nhắc lại, tham số thứ ba của mmap là chuỗi bit hoặc cờ
bảo vệ bộ nhớ (PROT_READ, PROT_WRITE, PROT_EXEC,
PROT_NONE). Khi CT cố thực hiện hoạt động không được
phép, nó bị chấm dứt bởi signal SIGSEGV.
Sau khi bộ nhớ được ánh xạ, các quyền trên có thể được
sửa đổi bởi system call mprotect(ts1, ts2, ts3):
ts1: địa chỉ vùng nhớ
ts2: kích thước vùng nhớ
ts3: tập các cờ bảo vệ
12
Listing 8.7: mprotect.c
1. CT cài đặt hàm xử lý tín hiệu SIGSEGV
2. định vị 1 trang bộ nhớ bằng việc ánh xạ /dev/zero và
ghi 1 giá trị lên đó để thu được một bản copy riêng
3. bảo vệ bộ nhớ bằng cách gọi mprotect với tham số
PROT_NONE
4. sau đó CT ghi lên bộ nhớ, Linux gửi tín hiệu
SIGSEGV, hàm xử lý tín hiệu gỡ bỏ bảo vệ, cho
phép truy nhập bộ nhớ để ghi.
5. khi hàm xử lý hoàn thành, quyền điều khiển trở về
main, CT dùng munmap để bỏ định vị bộ nhớ.
13
6.6. nanosleep: high-precision sleeping
Là phiên bản có độ chính xác cao (nano giây) của
system call UNIX chuẩn sleep
Hữu dụng khi cần lập lịch cho các hoạt động thường
xuyên có khoảng thời gian xen giữa rất nhỏ.
Cấu trúc struct timespec có 2 trường:
tv_sec: số giây nguyên
tv_nsec: số mili giây cộng thêm
nanosleep có tham số thứ hai là con trỏ tới 1 đối
tượng struct timespec khi khác null sẽ bằng
lượng thời gian còn lại, giúp việc tiếp tục lại hoạt
động ngủ dễ dàng hơn.
14
Ví dụ
Listing 8.8 (better_sleep.c): hàm nhận một giá trị thực
là số giây ngủ và khởi động lại hoạt động ngủ nếu nó
được ngắt bởi 1 signal.
15
6.7. sendfile: truyền dữ liệu nhanh
Cung cấp cơ chế hiệu quả để copy dữ liệu từ một file
descriptor này tới một file descriptor khác.
Không truyền qua buffer trung gian
File descriptor có thể là các tệp, socket, các thiết bị
khác.
Các tham số:
file descriptor để ghi lên
file descriptor để đọc ra
con trỏ tới biến offset: bắt đầu đọc từ offset này của file
số byte cần truyền
Giá trị trả về là số byte đã được truyền
16
Chương trình ví dụ
Listing 8.10 (copy.c): Chương trình đơn giản nhưng
thực thi copy file vô cùng hiệu quả.
gọi chương trình với 2 tên file trên dòng lệnh
sử dụng fstat để xác định kích thước của file nguồn (byte)
Có thể sử dụng sendfile trong nhiều nơi để giúp
việc copy hiệu quả hơn.
Vd: Web server và các ứng dụng mạng khác.
Thông thường, một yêu cầu được nhận từ socket nối với
máy client. Chương trình server mở file trên đĩa của mình để
nhận dữ liệu cần thiết và ghi nội dung file lên socket mạng.
Sử dụng sendfile có thể tăng tốc đáng kể hoạt động trên.
17
6.8. setitimer: setting interval timers
Lập lịch việc phát đi một signal tại một số thời điểm
trong tương lai sau khoảng thời gian ấn định trước.
Một chương trình có thể thiết lập 3 dạng timer khác
nhau tùy theo truyền timer code:
ITIMER_REAL: tiến trình được gửi signal SIGALRM sau
khoảng thời gian wall-clock xác định.
ITIMER_VIRTUAL: tiến trình được gửi signal SIGVTALRM
sau khi tiến trình thực hiện được khoảng thời gian xác định.
Thời gian tiến trình không thực hiện (khi kernel hoặc tiến
trình khác chạy) không được tính.
ITIMER_PROF: tiến trình được gửi signal SIGPROF khi hết
khoảng thời gian định trước, tính cả thời gian tiến trình thực
hiện và thời gian thực hiện các system call gọi bởi tiến trình.
18
setitimer (tiếp)
Các tham số:
ts1: timer code
ts2: con trỏ tới đối tượng struct itimerval, xác định
thiết lập mới cho timer đó.
ts3: nếu khác Null thì là con trỏ tới đối tượng struct
itimerval khác để nhận các thiết lập timer cũ.
Biến struct itimerval có 2 trường:
it_value: chứa thời gian tính đến lần hết hạn tiếp theo của
timer và 1 signal được gửi. nếu =0 thì timer là disable.
it_interval: chứa giá trị mà timer sẽ được thiết lập lại
sau khi hết hạn. nếu =0 thì timer là disable sau khi hết hạn.
19
Chương trình ví dụ
Listing 8.11 (itimer.c): minh họa sử dụng setitimer
để theo dõi thời gian thực hiện của 1 chương trình.
1 timer được cấu hình hết hạn sau mỗi 250 ms và gửi 1
signal SIGVTALRM.
20
6.9. sysinfo: lấy thống kê hệ thống
Tham số duy nhất là con trỏ tới biến struct sysinfo
Một số trường quan trọng của struct sysinfor:
uptime: thời gian tính từ khi hệ thống được khởi động (giây)
totalram: tổng dung lượng RAM khả dụng
freeram: dung lượng RAM còn trống
procs: số lượng tiến trình trong hệ thống
Để sử dụng sysinfo, bao gồm các thư viện:
,,
Listing 8.12 (sysinfo.c): in ra một số thống kê hệ thống ở
thời điểm hiện tại.
21
6.10. uname
Dùng để lấy nhiều thông tin hệ thống như network name
và domain name của máy tính, phiên bản HĐH
Tham số duy nhất: con trỏ tới đối tượng struct utsname,
gồm các trường:
sysname: tên của HĐH (vd: Linux)
release, version: số hiệu phát hành và phiên bản của Linux kernel.
machine: một số thông tin về nền phần cứng chạy Linux. Với Linux
x86, đó là i386 hoặc i686.
node:hostname tuyệt đối của máy tính
domain: domain name của máy tính
Listing 8.13 (print_uname.c): in một số thông tin của Linux