thực hành unix, linux (3) ngô thanh nguyên bộ môn hệ thống và mạng máy tính

50
Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính Khoa Khoa học và kỹ thuật máy tính Email: [email protected] Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 1

Upload: asis

Post on 13-Jan-2016

40 views

Category:

Documents


2 download

DESCRIPTION

Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính Khoa Khoa học và kỹ thuật máy tính Email: [email protected]. Lập trình trên Linux. Lập trình IPC Dùng pipe Dùng signal Dùng semaphore. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Thực hành Unix, Linux (3)

Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Khoa Khoa học và kỹ thuật máy tính

Email: [email protected]

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 1

Page 2: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Lập trình trên Linux Lập trình IPC

Dùng pipeDùng signalDùng semaphore

2Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM

Page 3: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Lập trình trên Linux Lập trình IPC

Dùng pipeDùng signalDùng semaphore

3Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM

Page 4: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Giới thiệu về IPCMục tiêu của IPC

IPC: Inter-Process CommunicationCho phép phối hợp hoạt động giữa các quá trình trong hệ

thốngGiải quyết đụng độ trên vùng tranh chấpTruyền thông điệp từ quá trình này đến các quá trình khácChia sẻ thông tin giữa các quá trình với nhau

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 4

Page 5: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Giao tiếp và đồng bộ Communication

Truyền dữ liệuChia sẻ thông tinCác cơ chế:

PipeSignalMessage queueShared memorySocketRPC/RMI

SynchronizationGiải quyết tranh chấpĐảm bảo thứ tự xử lýCác cơ chế:

Lock fileSemaphoreMutex (pthread)

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 5

Page 6: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Lập trình trên Linux Lập trình IPC

Dùng pipeDùng signalDùng semaphore

6Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM

Page 7: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Giao tiếp thông qua PIPE Là kênh truyền dữ liệu giữa các process với nhau theo

dạng FIFO

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 7

Page 8: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Các tác vụ trên pipe Write:

#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count)

Read:#include <unistd.h>ssize_t read(int fd, const void *buf, size_t count)

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 8

Page 9: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Hai loại pipe Unnamed pipe

có ý nghĩa cục bộchỉ dành cho các process có quan hệ bố con với nhau

Named pipe (còn gọi là FIFO)có ý nghĩa toàn cụccó thể sử dụng cho các process không liên quan bố con

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 9

Page 10: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Unnamed pipe Tạo unnamed pipe:

#include <unistd.h>int pipe(int filedes[2]);

Kết quảThành công, kết quả thực thi hàm pipe() là 0, có hai file

descriptor tương ứng sẽ được trả về trong filedes[0], filedes[1]

Thất bại: hàm pipe() trả về -1, mã lỗi trong biến ngoại errno

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 10

Page 11: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Unnamed pipe (2)

DuplexLinux: unidirectional/half-duplex, i.e. filedes[0] chỉ được dùng để

đọc còn filedes[1] chỉ được dùng để ghi dữ liệuSolaris: full-duplex, i.e. nếu ghi vào filedes[0], thì filedes[1] được

dùng để đọc và ngược lại

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 11

Page 12: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ về unnamed pipe #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>int main() {

int fp[2];char s1[BUFSIZ];char s2[BUFSIZ];pipe(fp);if (fork()==0) { /* Child Read */

printf("\nInput: ");fgets(s1, BUFSIZ, stdin);s1[strlen(s1)]=0;close(fp[0]);write(fp[1], s1, strlen(s1)+1);

} else { /* Parent Write */close(fp[1]);read(fp[0], s2, BUFSIZ);printf("\nFrom pipe>%s\n", s2);

}return 0;

} Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 12

Dịch, thực thi

$gcc unnamedpipe.c -o

unnamedpipe

$./unnamedpipe

Input: I Love Penguin

From pipe>I Love Penguin

$

Page 13: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Dùng pipe để tái định hướng Pipe có thể được dùng để kết nối các lệnh với nhau (do chương

trình shell thực hiện)Vídụ: $ps -ef | grep a01 | sort

$ls | moreĐối với chương trình người dùng, có thể dùng một trong hai

system call sau kết hợp với pipe đểthực hiện:dup() dup2()

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 13

Page 14: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

dup() #include <unistd.h>int dup(int oldfd);

Chức năng: tạo bản sao của descriptor oldfd. File descriptor nhỏ nhất còn chưa sử dụng sẽ là bản sao của oldfd.

Kết quảcủa hàm dup() Thành công: file descriptor bản sao Lỗi: -1 (mã lỗi trong biến ngoại errno)

File descriptor mới có những thuộc tính chung với file ban đầu Cùng chỉ đến một file (hay pipe) đang mở Chia sẻ cùng một file pointer Có cùng một chế độ truy cập (read, write hoặc read/write)

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 14

Page 15: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

dup2() #include <unistd.h>int dup2(int oldfd, int newfd);

Tương tự dup(), nhưng dup2() cho phép chỉ định file descriptor đích

Descriptor newfd trỏ đến cùng một file như oldfd

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 15

Page 16: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụfile dup.c

#include <unistd.h>int main() { // ps -ef | sort | grep

int pipe1[2], pipe2[2];pipe(pipe1);if (fork()) { /* Parent */

pipe(pipe2); if(fork()) { /* Parent */

close(0); // Close standard inputdup(pipe2[0]); // standard input -> Read

Pipe2close(pipe1[0]); close(pipe1[1]); close(pipe2[0]); close(pipe2[1]); execl("/bin/grep", "grep", "ps", NULL);

}Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 16

Page 17: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ (2)else { /* Child */

close(0); // Close standard inputdup(pipe1[0]); // standard input -> Read Pipe1close(1); // Close standard outputdup(pipe2[1]); // standard output -> Write Pipe2 close(pipe1[0]); close(pipe1[1]); close(pipe2[0]); close(pipe2[1]); execl("/bin/sort", "sort", NULL);

} } else { /* Parent */

close(1); // Close standard outputdup(pipe1[1]); // standard output -> Write Pipe1close(pipe1[0]); close(pipe1[1]); execl("/bin/ps", "ps", "-ef", NULL);

} exit(0);

}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 17

Page 18: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Named pipe Tương tự như unnamed pipeMột số tính năng cần chú ý:

Được ghi nhận trên file system (directory entry, file permission)

Có thể dùng với các process không có quan hệ bố conCó thể tạo ra từ dấu nhắc lệnh shell (bằng lệnh mknod)

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 18

Page 19: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Tạo named pipe - mknod() System call:

#include <sys/types.h>#include <sys/stat.h>int mknod(const char *path, mode_t mode, dev_t dev);

Trong đópath: đường dẫn đến pipe (trên file system)mode: quyền truy cập trên file = S_IFIFO kết hợp với trị khácdev: dùng giá trị 0

C/C++ library call#include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 19

Page 20: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụfifo.c#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/errno.h>extern int errno;

#define FIFO1 "/tmp/fifo.1"#define FIFO2 "/tmp/fifo.2"#define PERMS 0666int main(){

char s1[BUFSIZ], s2[BUFSIZ];int childpid, readfd, writefd;

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 20

Dịch và thực thi

$gcc fifo.c -o fifo

$./fifo

Parent inputs string and write

to FIFO1: Test1

Child read from FIFO1: Test1

Input string from child to

feedback: Test2

Feedback data from FIFO2: Test2

Page 21: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ (2)if ((mknod(FIFO1, S_IFIFO | PERMS, 0)<0) && (errno!=EEXIST)) {printf("can't create fifo1: %s", FIFO1);exit(1);

}if ((mknod(FIFO2, S_IFIFO | PERMS, 0)<0) && (errno!=EEXIST)) {unlink(FIFO1);printf("can't create fifo2: %s", FIFO2);exit(1);

}if ((childpid=fork())<0) {printf("can't fork");exit(1);

}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 21

Page 22: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ (3)else if (childpid>0) { /* parent */

if ((writefd=open(FIFO1,1))<0)perror("parent: can't open writefifo");

if ((readfd=open(FIFO2,0))<0)perror("parent: can't open readfifo");

printf("\nParent inputs string and write to FIFO1: ");gets(s1); s1[strlen(s1)]=0;write(writefd,s1,strlen(s1)+1);read(readfd,s2,BUFSIZ);printf("\nFeedback data from FIFO2: %s\n",s2);while (wait((int*)0)!=childpid); /* wait for child finish */close(readfd);close(writefd);if (unlink(FIFO1)<0) perror("Can't unlink FIFO1");if (unlink(FIFO2)<0) perror("Can't unlink FIFO2");exit(0);

}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 22

Page 23: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ (4)else { /* child */if ((readfd=open(FIFO1,0))<0)

perror("child: can't open readfifo");if ((writefd=open(FIFO2,1))<0)

perror("child: can't open writefifo");read(readfd,s2,BUFSIZ);printf("\nChild read from FIFO1: %s\n",s2);printf("\nInput string from child to feedback: ");gets(s1);s1[strlen(s1)]=0;write(writefd,s1,strlen(s1)+1);close(readfd);close(writefd);exit(0);

}}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 23

Page 24: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Lập trình trên Linux Lập trình IPC

Dùng pipeDùng signalDùng semaphore

24Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM

Page 25: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

SignalsDựa vào các sự kiện bất đồng bộ.Kernel có nhiệm vụ gửi (deliver) sự kiện đến processCác process có thể tự thiết lập các hành vi ứng xử tương

ứng với sự kiện nhận được.

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 25

Page 26: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Một số signals thường gặp SIGKILLSIGSTOPSIGHUPSIGPIPESIGINTSIGQUIT…

Tham khảo thêm dùng các lệnh sau$ man 7 signal hoặc info signal$ kill -l$ more /usr/include/bits/signum.h

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 26

Page 27: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Các signalSignal Value Action Comment

------------------------------------------------------------------------- SIGHUP 1 Term Hangup detected on controlling terminal or death of controlling process SIGINT 2 Term Interrupt from keyboard SIGQUIT 3 Core Quit from keyboard SIGILL 4 Core Illegal Instruction SIGABRT 6 Core Abort signal from abort(3) SIGFPE 8 Core Floating point exception SIGKILL 9 Term Kill signal SIGSEGV 11 Core Invalid memory reference SIGPIPE 13 Term Broken pipe: write to pipe with no readers SIGALRM 14 Term Timer signal from alarm(2) SIGTERM 15 Term Termination signal SIGUSR1 30,10,16 Term User-defined signal 1 SIGUSR2 31,12,17 Term User-defined signal 2 SIGCHLD 20,17,18 Ign Child stopped or terminated SIGCONT 19,18,25 Continue if stopped SIGSTOP 17,19,23 Stop Stop process SIGTSTP 18,20,24 Stop Stop typed at tty SIGTTIN 21,21,26 Stop tty input for background process SIGTTOU 22,22,27 Stop tty output for background process

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 27

Page 28: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Hành vi của process đối với một sự kiện Các hành vi có thể thực hiện khi có sự kiện

Thực hiện các hành vi mặc định (do hệ điều hành qui định) TERMINATED/ABORT - kết thúc CORE (Dump) - tạo ra core image (memory dump) và thoát STOP – Trì hoãn thực thi

IGNORE - Bỏ qua signal (ngoại trừ SIGKILL, SIGSTOP)CATCH - Thực hiện hành vi do người lập trình định nghĩa

(signal handler).

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 28

Page 29: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Các nguồn tạo signal Từ kernel

Khi xảy ra một số điều kiện về phần cứng (SIGSEGV, SIGFPE)Khi xảy ra điều kiện phần mềm (SIGIO)

Từ userTổ hợp phím: Ctrl+C, Ctrl+Z, Ctrl+\Khi user dùng lệnh kill

Từ một process thực hiện system call kill()#include <sys/types.h>#include <signal.h>int kill(pid_t pid, int sig);

Từ lời gọi system call alarm() → tạo ra SIGALRM

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 29

Page 30: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Lập trình với signal #include <signal.h>typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

int sighold(int sig);int sigrelse(int sig);int sigignore(int sig);int sigpause(int sig);

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 30

Page 31: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Lập trình với signal (2)sighandler_t signal(int signum, sighandler_t handler);

Thay đổi hành vi của process đối với signalTham số của hàm signal()

signum: là số hiệu signal mà bạn muốn thay đổi hành vi (trừ SIGKILL hay SIGSTOP) - dạng số hay symbolic

handler: hành vi mới đối với signal, các giá trị có thể là: SIG_DFL: thiết lập lại hành vi về mặc định (default) SIG_IGN: lờ đi (ignore) signal tương ứng Tham chiếu đến hàm xử lý sự kiện (signal-handler) mới do người

dùng tự định nghĩa

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 31

Page 32: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ lập trình với signal

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 32

Bỏ qua signal (sigign.c)

#include <stdio.h>#include <signal.h>#include <unistd.h>#include <stdlib.h>int main() {

if (signal(SIGINT, SIG_IGN)==SIG_ERR) {

perror("SIGINT\n");exit(3);

}while (1);return 0;

}

Lưu ý: SIGINT tạo ra khi user nhấn Ctrl+C để kết thúc process đang thực thi

Dịch vàthực thi

$gcc sigign.c –o sigign

$./sigign

^C

^C

^C

Page 33: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ lập trình với signal (2)Định nghĩa hành vi mới đối với tín hiệu SIGINT(sig2.c)

#include <stdio.h>#include <signal.h>#include <unistd.h>#include <stdlib.h>void newhandler(int sig) {

printf("\nI received signal %d",sig);}int main() {

int i=0;if (signal(SIGINT,newhandler)==SIG_ERR){

perror("\nSIGINT");exit(3);

}while (1);return 0;

}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 33

Dịch vàthực thi

$gcc sig2.c -o sig2

$./sig2

^C

I received signal 2

^C

I received signal 2

^C

I received signal 2

Page 34: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Lập trình trên Linux Lập trình IPC

Dùng pipeDùng signalDùng semaphore

34Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM

Page 35: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

SystemV IPC Gồm: message queue, shared memory, semaphoreCó một số thuộc tính chung như

Người tạo, người sở hữu (owner), quyền truy cập (perms)Có thể theo dõi trạng thái các IPC bằng lệnh ipcs

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 35

$ipcs------Shared Memory Segments --------key shmid owner perms bytes nattch status 0x00000000 65536 root 644 110592 11 dest

------Semaphore Arrays --------key semid owner perms nsems

------Message Queues --------key msqid owner perms used-bytes messages

Page 36: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Semaphore Đồng bộ các process theo giải thuật của semaphoreBiến semaphore

số nguyên, truy cập qua các hàm do hệ điều hành cung cấp: P (wait), V (signal)

Đảm bảo loại trừ tương hỗTrong UNIX System V, semaphore được dùng theo set –

danh sách các semaphore.

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 36

Page 37: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Lệnh IPC trong Linux Theo dõi trạng thái các IPC (gồm message queue,

semaphore, shared memory)ipcs hoặc ipcs -a

Theo dõi trạng thái các semaphore của hệ thốngipcs -s

Loại bỏ một semaphore (phải đủ quyền hạn)ipcrm sem semid hoặc ipcrm -s semid

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 37

Page 38: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Các thao tác chủ yếu trên đối tượng IPC Tác vụ get

tạo các đối tượng IPC.semget()

Tác vụ điều khiển: lấy hoặc thay đổi thuộc tính của các đối tượng IPC semctl()

Specific operationsthay đổi trạng thái hay nội dung của đối tượng IPC nhằm

tương tác với quá trình khác.semop()

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 38

Page 39: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Hàm semget() Tạo semaphore:

#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semget(key_t key, int nsems, int semflg); key: giá trị key cho IPC object, nếu key=IPC_PRIVATE thì semaphore tạo ra

chỉ được sử dụng trong nội bộ process. nsems: số lượng semaphore trong semaphore set, thông thường chỉ cần dùng 1

semaphore. semflag: IPC_CREAT, IPC_EXCL và có thể OR với giá trị ấn định quyền truy

cập (tương tự quyền hạn trên một file). Ví dụ

sset1_id=semget(IPC_PRIVATE,1,IPC_CREAT|IPC_EXCL|0600);sset2_id=semget(12345,1,IPC_CREAT|IPC_EXCL|0666);

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 39

Page 40: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Tạo key cho IPC object Mỗi IPC object (là một khối shared memory hoặc một semaphore)

được xác định bởi số danh định gọi là key. key kiểu là key_t

Process truy cập một IPC_object thông qua key của đối tượng đó.Cách tạo một IPC key dùng hàm ftok()

#include <sys/types.h>#include <sys/ipc.h>keyt_t key;char *path;int id=123;...key=ftok(path,id);

⇒ các process khác nhau chỉ cần cung cấp path và id giống nhau là có thể tạo đúng key truy cập đến cùng một IPC object.

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 40

Page 41: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Hàm semop() Thực hiện các thao tác trên semaphore

#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semop(int semid, struct sembuf *sops, size_t nsops);

semid: semaphore set ID do hàm semget() trảvề nsops: số semaphores trong semaphore cần thao tác sops: là danh sách gồm nsops cấu trúc sembuf định ra các thao tác

cho từng semaphore trong tập semaphore.

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 41

Page 42: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Hàm semop() (2)Cấu trúc sembuf

struct sembuf {ushort sem_num; /*semaphore thứ #*/short sem_op; /*operation*/short sem_flg;/*operation flags*/

} sem_num: chỉ số của semaphore trong semaphore set, chỉ số này bắt đầu

từ 0 sem_op: là số nguyên

>0: tăng giá trị semaphore <0: giảm giá trị semaphore

sem_flg: IPC_NOWAIT: non-blocking mode SEM_UNDO: undo operation

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 42

Page 43: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Hành vi của hàm semop() semop<0

semval ≥abs(semop)semval=semval-abs(semop)

semval ≥abs(semop) & SEM_UNDOsemval-=abs(semop) AND semadj+=abs(semop)

semval<abs(semop)block until semval ≥abs(semop)

semval<abs(semop) & IPC_NOWAITreturn -1, errno=EAGAIN

semop>0semval+=semopSEM_UNDO

semval+=semop AND semadj-=semop

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 43

Page 44: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Hàm semctl()Thực hiện các tác vụ thay đổi trạng thái semaphore:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semctl(int semid,int semnum,int cmd);int semctl(int semid,int semnum,int cmd, unionsemun arg);

union semun{int val;struct semid_ds *buf;ushort *array;

};

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 44

Page 45: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Hàm semctl() - tham số cmd Các thao tác thông thường

IPC_SET : thiết lập quyền truy cập IPC_STAT: lấy thông tin thuộc tính IPC_RMID: xoá semaphore set

Các thao tác trên từng semaphore riêng lẻGETVAL: lấy thông tin thuộc tínhSETVAL: thay đổi thuộc tínhGETPID: lấy PID của process vừa truy cập semaphoreGETNCNT: lấy số process đang đợi semval tăng lênGETZCNT: lấy số process đang đợi semval về 0

Các thao tác trên toàn semaphore setSETALL: thay đổi thuộc tínhGETALL: lấy thông tin thuộc tính

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 45

Page 46: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụHiện thực 4 hàm cơ bản của semaphore

seminit: tạo binary semaphorep (wait)v (signal)semrel: xoá semaphore

Viết chương trình giải quyết tranh chấp dùng semaphore

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 46

Page 47: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ (sema.c) #include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <errno.h>#include <unistd.h>union {

int val;struct semid_ds *buf;ushort *array;

} carg;int seminit() {

int i, semid;if (semid=semget(IPC_PRIVATE,1,0666|IPC_EXCL)==-1) return(-1);carg.val=1;if (semctl(semid,0,SETVAL,carg)==-1) return(-1);return semid;

}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 47

Page 48: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ (sema.c) (2)void p(int sem){

struct sembuf pbuf;pbuf.sem_num=0;pbuf.sem_op=-1; /* giaWm giá trị semaphore */pbuf.sem_flg=SEM_UNDO;if (semop(sem,&pbuf,1)==-1) {perror("semop");exit(1);

}}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 48

Page 49: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ (sema.c) (3)void v(int sem){

struct sembuf vbuf;vbuf.sem_num=0;vbuf.sem_op=1;vbuf.sem_flg=SEM_UNDO;if (semop(sem,&vbuf,1)==-1) {perror("semop");exit(1);

}}int semrel(int semid){return semctl(semid,0,IPC_RMID,0);

}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 49

Page 50: Thực hành Unix, Linux (3) Ngô Thanh Nguyên Bộ môn Hệ thống và Mạng máy tính

Ví dụ (sema.c)void func(int sem) {

while(1) {p(sem); /* enter section */printf("%d Do something in CS\n",getpid());sleep(5);v(sem); /* exit section */printf("\n%d Out of CS\n",getpid());sleep(1);

}}void main() {

int sem;sem=seminit();if (fork()==0) func(sem);else func(sem);

}

Khoa KH&KTMT - Đại học Bách Khoa Tp. HCM 50