Ch4 Linux System Programming – Process & IPC
description
Transcript of Ch4 Linux System Programming – Process & IPC
![Page 1: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/1.jpg)
Ch4 Linux System Programming – Process & IPC
Jianjian SONGSoftware Institute, Nanjing UniversityOct, 2004
![Page 2: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/2.jpg)
Content
1. Process & process environment2. Process Control
Process identifier, fork, exec…3. Process relationship4. Signal5. Inter-process communication (IPC)
Pipe, FIFO semaphore, shared memory, message
queue6. Daemon7. Thread
![Page 3: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/3.jpg)
1. Process & Process Environment
What is a process? Program and process Process: an address space with one or
more threads executing within that address space, and the required system resources for those threads. (SUSv3)
![Page 4: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/4.jpg)
The startup of a process
System call “fork” Process resources
struct task_struct System space stack …
System call “exec” The entry of C programs
![Page 5: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/5.jpg)
System stack
![Page 6: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/6.jpg)
The entry of C programs
crt0.o cc/ld
main function function prototype :
int main(int argc, char *argv[]);
![Page 7: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/7.jpg)
The termination of a process
Five ways of terminating a process Normal termination
Return from “main” function Call “exit” function Call “_exit” function
Abnormal termination Call “abort” function Terminated by a signal
![Page 8: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/8.jpg)
exit & _exit functions
Function prototype:#include <stdlib.h>void exit(int status);#include <unistd.h>void _exit(int status);
Exit status Difference
_exit is corresponding to a system call, while “exit” is a library function.
_exit terminate a process immediately.
![Page 9: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/9.jpg)
Exit handler
atexit function Register a function to be called at normal
program termination. Prototype:
#include <stdlib.h>int atexit(void (*function)(void));
on_exit function Example
![Page 10: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/10.jpg)
![Page 11: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/11.jpg)
The memory map of a C program
Text segment (code segment) Data segment
Initialized data Uninitialized data Heap
Stack
![Page 12: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/12.jpg)
![Page 13: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/13.jpg)
Command line arguments
main functionint main(int argc, char *argv[]);
Example: The implementation of echo(1)
Command line option Standard usage getopt function
![Page 14: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/14.jpg)
getopt function Prototype:
int getopt(int argc, char *const argv[], const char *optstring);extern char *optarg;extern int optind, opterr, optopt;
Question : getopt(argc, argv, “if:lr”); Program example (P104, in BLP)
![Page 15: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/15.jpg)
Environment variables
Environment table Environment pointer
extern char **environ;
![Page 16: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/16.jpg)
putenv & getenv functions Get, set or unset an environment varia
ble#include <stdlib.h>char *getenv(const char *name);int putenv(char *string);int setenv(const char *name, const char *value, in
t overwirte);void unsetenv(const char *name);
![Page 17: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/17.jpg)
Shared object
Shared object Dynamic link Advantages and disadvantages Example
How to create a static and shared library? How to use (link) a static or shared
library?
![Page 18: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/18.jpg)
Memory allocation
Allocate and free dynamic memory.#include <stdlib.h>void *malloc(size_t size);void *calloc(size_t nmemb, size_t size);void free(void *ptr);void realloc(void *ptr, size_t size);
![Page 19: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/19.jpg)
2. Process control
Process identifier System call “fork” The simple synchronization
between parent and child process The “exec” function family Example:
The implementation of a simple shell
![Page 20: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/20.jpg)
Process identifier
![Page 21: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/21.jpg)
fork
fork: create a child process#include <sys/types.h>#include <unistd.h>pid_t fork(void);
returned value: pid of child (in the current (parent) process), 0 (in child process), -1 (failure)
![Page 22: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/22.jpg)
A simple example
#include <stdio.h>#include <sys/types.h>#include <unistd.h>
/* fork 系统调用的第一个例子(不含错误检查) */void main(){
printf(“Hello, world!\n”);fork();printf(“bye\n”);
}
![Page 23: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/23.jpg)
The usage of “fork” Code example
if ( (pid=fork()) < 0) { /* error handling */} else if (pid == 0) { /* child */} else { /* parent */};
Program example Program8-1 in APUE
![Page 24: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/24.jpg)
File sharing 所有由父进程打开的描述符都被复制到子进程
中。父、子进程每个相同的打开描述符共享一个文件表项
![Page 25: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/25.jpg)
![Page 26: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/26.jpg)
vfork & clone functions vfork
#include <sys/types.h>#include <unistd.h>pid_t vfork(void);
clone#include <sched.h>int clone(int (*fn)(void *), void *child_stack,
int flag, void *arg);
![Page 27: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/27.jpg)
The simple synchronization between parent and child process
The relationship between parent and child process
wait and waitpid functions
![Page 28: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/28.jpg)
The relationship between parent and child process
The parent terminates before the child Orphan process
The child terminates before the parent SIGCHLD signal Handled by wait/waitpid in parent Not handled by wait/wait in parent -> zombi
e
![Page 29: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/29.jpg)
wait & waitpid functions Wait for process termination Prototype
#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *status);pid_t waitpid(pid_t pid, int *status, int options);
Example
![Page 30: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/30.jpg)
Race condition
int main(void){ pid_t pid;
if ( (pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) { charatatime("output cccccccccccc from child\n"); } else { charatatime("output pppppppppp from parent\n"); } exit(0);}
![Page 31: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/31.jpg)
An improvementint main(void){ pid_t pid; TELL_WAIT(); if ( (pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) { WAIT_PARENT(); /* parent goes first */ charatatime("output cccccccccccc from child\n"); } else { charatatime("output pppppppppp from parent\n"); TELL_CHILD(pid); } exit(0);}
![Page 32: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/32.jpg)
The “exec” family of functions
Replace the current process image with a new process image.
执行新程序的进程保持原进程的一系列特征: pid, ppid, uid, gid, working directory, root direc
tory … euid/egid? 打开文件描述符 ?
![Page 33: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/33.jpg)
Functions prototypes
#include <unistd.h>extern char **environ;int execl(const char *path, const char *arg, ...);int execlp(const char *file, const char *arg, ...);int execle(const char *path, const char *arg, ..., char *
const envp[]);int execv(const char *path, char * const argv[]);int execvp(const char *file, char * const argv[]);
#include <unistd.h>int execve(const char *filename, char * const argv[], c
har * const envp[]);
![Page 34: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/34.jpg)
![Page 35: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/35.jpg)
![Page 36: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/36.jpg)
exec and opened file descriptor
close-on-exec bit of a file descriptor Set by “fcntl” function
fcntl(fd, F_SETFD, 0); /* 系统默认 , 打开文件描述符在 exec 时不关闭 */
fcntl(fd, F_SETFD, 1); /* 打开文件描述符在 exec 时关闭 */
![Page 37: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/37.jpg)
Using fork and exec together
Two ways of using fork The parent process duplicates itself, and then tw
o different pieces of codes are executed in parent process and child process.
A process want to execute another program. Example:
The implementation of “system” function int system(const char*cmdstring);
![Page 38: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/38.jpg)
Example: a simple shellprintf("%% "); /* print prompt */while (fgets(buf, MAXLINE, stdin) != NULL) { buf[strlen(buf) - 1] = 0; /* replace newline with null */ if ( (pid = fork()) < 0 ) err_sys(“fork error”); else if ( pid == 0 ) { /* child */ execlp(buf, buf, (char *) 0); fprintf(stderr, "couldn't execute: %s", buf); exit(127); } if ( (pid = waitpid(pid, &status, 0)) < 0 ) /* parent */ err_sys(“waitpid error”); printf("%% ");}
![Page 39: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/39.jpg)
3. Process relationship
父进程和子进程 进程树
ps, pstree 命令
![Page 40: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/40.jpg)
Startup & login (1)
Login on serial terminal
![Page 41: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/41.jpg)
![Page 42: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/42.jpg)
Startup & login (2)
Network login
![Page 43: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/43.jpg)
Process group & session
Process group The set of one or more process(es). getpgrp/setpgid functions
Session The set of one or more process group(s). setsid function
Controlling terminal Why are they introduced?
Job control
![Page 44: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/44.jpg)
Process group & session (cont’d)
![Page 45: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/45.jpg)
Process group & session (cont’d)
![Page 46: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/46.jpg)
4. Signal
The concept of signals The “signal” function Send a signal
kill, raise The “alarm” and “pause” functions Reliable signal mechanism
![Page 47: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/47.jpg)
The concept of signals
Signal Software interrupt Mechanism for handling asynchronous events Having a name (beginning with SIG) Defined as a positive integer (in <signal.h>)
How to produce a signal 按终端键,硬件异常, kill(2) 函数, kill(1) 命令,
软件条件, ...
![Page 48: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/48.jpg)
Signals in Linux/UNIX
名称 说明SIGABRT 进程异常终止(调用 abort 函数产生此信号)SIGALRM 超时( alarm )SIGFPE 算术运算异常(除以 0 ,浮点溢出等)SIGHUP 连接断开SIGILL 非法硬件指令SIGINT 终端终端符 (Clt-C)SIGKILL 终止(不能被捕捉或忽略)SIGPIPE 向没有读进程的管道写数据SIGQUIT 终端退出符 (Clt-\)SIGTERM 终止(由 kill 命令发出的系统默认终止信号)SIGUSR1 用户定义信号SIGUSR2 用户定义信号
![Page 49: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/49.jpg)
Signals in Linux/UNIX (cont’d)
名称 说明SIGSEGV 无效存储访问(段违例)SIGCHLD 子进程停止或退出SIGCONT 使暂停进程继续SIGSTOP 停止(不能被捕捉或忽略)SIGTSTP 终端挂起符 (Clt-Z)SIGTTIN 后台进程请求从控制终端读SIGTTOUT 后台进程请求向控制终端写
![Page 50: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/50.jpg)
Signal handling
忽略信号 不能忽略的信号:
SIGKILL, SIGSTOP 一些硬件异常信号
执行系统默认动作 捕捉信号
![Page 51: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/51.jpg)
The “signal” function
Installs a new signal handler for the signal with number signum.
#include <signal.h>typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);
(Returned Value: the previous handler if success, SIG_ERR if error)
The “handler” parameter a user specified function, or SIG_DEF, or SIG_IGN
![Page 52: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/52.jpg)
The ”signal” function (cont’d) Program example
static void sig_usr(int);int main(void){ if (signal(SIGUSR1, sig_usr) == SIG_ERR) err_sys("can't catch SIGUSR1"); if (signal(SIGUSR2, sig_usr) == SIG_ERR) err_sys("can't catch SIGUSR2");
for ( ; ; ) pause();}
![Page 53: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/53.jpg)
Send a signal
kill(2): send signal to a process#include <sys/types.h>#include <signal.h>int kill(pid_t pid, int sig);
(Returned Value: 0 if success, -1 if failure) raise(3): send a signal to the current process
#include <signal.h>int raise(int sig);
(Returned Value: 0 if success, -1 if failure)
![Page 54: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/54.jpg)
alarm & pause functions
alarm: set an alarm clock for delivery of a signal#include <unistd.h>unsigned int alarm(unsigned int seconds);
(Returned value: 0, or the number of seconds remaining of previous alarm)
pause: wait for a signal#include <unistd.h>int pause(void);
(Returned value: -1, errno is set to be EINTR)
![Page 55: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/55.jpg)
alarm & pause functions (cont’d)
Program example The implementation of the “sleep” fun
ctionunsigned int sleep1(unsigned int nsecs){ if ( signal(SIGALRM, sig_alrm) == SIG_ERR) return(nsecs); alarm(nsecs); /* start the timer */ pause(); /*next caught signal wakes us up*/ return(alarm(0) ); /*turn off timer, return unslept time */}
![Page 56: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/56.jpg)
Possible problems
Problems related to time Race condition Interrupted system calls Reentrancy
![Page 57: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/57.jpg)
Reliable signal mechanism
Weakness of the signal function Signal block
signal mask Signal set
sigset_t data type Signal handling functions using signal set
sigprocmask, sigaction, sigpending, sigsuspend
![Page 58: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/58.jpg)
signal set operations
#include <signal.h>
int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset(sigset_t *set, int signum);int sigdelset(sigset_t *set, int signum); (Return value: 0 if success, -1 if error)
int sigismember(const sigset_t *set, int signum); (Return value: 1 if true, 0 if false)
![Page 59: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/59.jpg)
sigprocmask function 检测或更改 ( 或两者 ) 进程的信号掩码
#include <signal.h>sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
(Return Value: 0 is success, -1 if failure)
参数“ how” 决定对信号掩码的操作 SIG_BLOCK: 将 set 中的信号添加到信号掩码 ( 并集 ) SIG_UNBLOCK: 从信号掩码中去掉 set 中的信号 ( 差集 ) SIG_SETMASK: 把信号掩码设置为 set 中的信号
例外 : SIGKILL, SIGSTOP
![Page 60: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/60.jpg)
sigpending function 返回当前未决的信号集
#include <signal.h>sigpending(sigset_t *set);
(Returned Value: 0 is success, -1 if failure)
Example: critical.c (Prog10-11 in APUE)
![Page 61: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/61.jpg)
sigaction function 检查或修改 ( 或两者 )与指定信号关联的处理动作
#include <signal.h>sigaction(int signum, const struct sigaction *act, struct sigac
tion *oldact);(Returned Value: 0 is success, -1 if f
ailure) struct sigaction至少包含以下成员 :
handler_t sa_handler; /* addr of signal handler, or SIG_IGN, or SIG_DEL */
sigset_t sa_mask;/* additional signals to block */int sa_flags; /* signal options */
![Page 62: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/62.jpg)
![Page 63: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/63.jpg)
sigsuspend function 用 sigmask临时替换信号掩码,在捕捉一个信号或发
生终止该进程的信号前,进程挂起。#include <signal.h>sigsuspend(const sigset *sigmask);
(Returned value: -1, errno is set to be EINTR) sigsuspend 和 pause
![Page 64: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/64.jpg)
signal function review 用 sigaction实现 signal 函数
Sigfunc * signal(int signo, handler_t func) {struct sigaction act, oact;act.sa_handler = func;sigemptyset(&act.sa_mask);act.sa_flags = 0;if (signo == SIGALRM) {
#ifdef SA_INTERRUPTact.sa_flags |= SA_INTERRUPT; /* SunOS */
#endif} else {
#ifdef SA_RESTARTact.sa_flags |= SA_RESTART; /* SVR4, 44BSD */
#endif}if (sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);return(oact.sa_handler);
}
![Page 65: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/65.jpg)
Example: solution of race conditionint main(void){ pid_t pid; TELL_WAIT(); if ( (pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) { WAIT_PARENT(); /* parent goes first */ charatatime("output cccccccccccc from child\n"); } else { charatatime("output pppppppppp from parent\n"); TELL_CHILD(pid); } exit(0);}
![Page 66: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/66.jpg)
static sigset_t newmask, oldmask, zeromask;static void sig_usr(int signo) {/* one handler for SIGUSR1, SIGUSR2 */
sigflag = 1; return;}void TELL_WAIT() {
if (signal(SIGUSR1, sig_usr) == SIG_ERR)err_sys("signal(SIGINT) error");
if (signal(SIGUSR2, sig_usr) == SIG_ERR)err_sys("signal(SIGQUIT) error");
sigemptyset(&zeromask);sigemptyset(&newmask);sigaddset(&newmask, SIGUSR1);sigaddset(&newmask, SIGUSR2);
/* block SIGUSR1 and SIGUSR2, and save current signal mask */if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error");}
![Page 67: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/67.jpg)
void WAIT_PARENT(void) {while (sigflag == 0)
sigsuspend(&zeromask); /* and wait for parent */
sigflag = 0;/* reset signal mask to original value */if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");}
void TELL_CHILD(pid_t pid) {kill(pid, SIGUSR1); /* tell child we're done */
}
![Page 68: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/68.jpg)
5. Inter-process communication
IPC: Inter-Process Communication IPC mechanisms
shared file signal pipe, FIFO (named pipe), message
queue, semaphore, shared memory socket
![Page 69: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/69.jpg)
IPC illustrations
![Page 70: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/70.jpg)
Simple Client-Server or IPC model
![Page 71: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/71.jpg)
The concept of pipe
Pipe Pipe mechanism in a shell
e.g. cmd1 | cmd2 Pipe is half-duplex 管道只能在共同祖先的进程间使用 管道也是文件 命名管道 (FIFO)
![Page 72: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/72.jpg)
The pipe function
The pipe function: create a pipe#include <unistd.h>int pipe(int filedes[2]);
(Returned value: 0 if success, -1 if failure) A pipe: First In, First Out
filedes[0]:read, filedes[1]: write
![Page 73: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/73.jpg)
A pipe in a single process
![Page 74: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/74.jpg)
A pipe between the parent & child
![Page 75: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/75.jpg)
The coordinationof pipe read & write
写管道时,常数 PIPE_BUF规定了内核中管道缓存器的大小
管道的一端关闭时, 写端关闭,读该管道在所有数据都被读取后,
read返回 0 ,表示达到了文件结束 读端关闭,写该管道产生信号 SIGPIPE
![Page 76: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/76.jpg)
Examples
pipe1.c
![Page 77: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/77.jpg)
管道用于标准输入和标准输出 管道: shell 中的形式
cmd1 | cmd2 重定向 cmd > file
实现代码 执行 cmd1前
if (fd[1] != STDOUT_FILENO) {if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO)
err_sys(“dup2 error to stdout);}
执行 cmd2前if (fd[0] != STDIN_FILENO) {
if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) err_sys(“dup2 error to stdin);}
![Page 78: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/78.jpg)
![Page 79: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/79.jpg)
Examples
pipe2.c
![Page 80: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/80.jpg)
pipe Application(1):solution of race conditionint main(void){ pid_t pid; TELL_WAIT(); if ( (pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) { WAIT_PARENT(); /* parent goes first */ charatatime("output cccccccccccc from child\n"); } else { charatatime("output pppppppppp from parent\n"); TELL_CHILD(pid); } exit(0);}
![Page 81: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/81.jpg)
static int pfd[2];void TELL_WAIT() {
if (pipe(pfd) < 0)err_sys("pipe error");
}void WAIT_PARENT(void) {
char c;if (read(pfd[0], &c, 1) != 1)
err_sys("read error");if (c != 'p')
err_quit("WAIT_PARENT: incorrect data");}void TELL_CHILD(pid_t pid) {
if (write(pfd[1], "p", 1) != 1)err_sys("write error");
}
![Page 82: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/82.jpg)
pipe Application(2): shell
shpipe.c
![Page 83: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/83.jpg)
popen & pclose functions popen, pclose: process I/O
#include <stdio.h>FILE *popen(const char *command, const char *type);int pclose(FILE *stream);
![Page 84: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/84.jpg)
按页输出 在程序中获得另一个程序的输出
Applications of popen & pclose
![Page 85: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/85.jpg)
Home work: popen 的实现 用 pipe, fork实现 popen
![Page 86: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/86.jpg)
FIFO: named pipe
管道和命名管道 相同点 不同点
文件系统中 同步:一个重要的考虑
mkfifo(1), mkfifo(3), mknod(1), mknod(2)
![Page 87: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/87.jpg)
创建 FIFO mkfifo: make a FIFO special file (a named pi
pe)#include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);
(Returned value: 0 if success, -1 if failure) Examples
fifo1.c (Ch12 in BLP) list a fifo (ls –lF)
![Page 88: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/88.jpg)
用 open 打开一个 FIFO Review: “open” system call
int open(const char *pathname, int flags); “flags” parameter
必须指定的互斥模式 :O_RDONLY, O_WRONLY, O_RDWR
O_NONBLOCK consideration :
读端 / 写端 同步
![Page 89: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/89.jpg)
FIFO 的同步和读写 打开 FIFO 时的同步
一般情况下(没有说明 O_NONBLOCK ),只读打开要阻塞到某个其它进程为写打开此 FIFO;类似的,为写打开一个 FIFO要阻塞到某个其它进程为读而打开它。
如果指定了 O_NONBLOCK ,则只读打开立即返回;只写打开也立即返回,但如果没有进程已经为读而打开此 FIFO ,那么 open 将出错返回 -1 , errno置为 ENXIO 。
读写 FIFO 时的同步 same as pipe
![Page 90: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/90.jpg)
同步示例 shell 中使用 fifo 的例子
cat < my_fifoecho “a string to fifo” > my_fifo
fifo2.c (Ch12 in BLP)
![Page 91: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/91.jpg)
FIFO 的应用 (1) 用 FIFO 复制输出流
例
![Page 92: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/92.jpg)
FIFO 的应用 (2) C/S应用程序
例: client.c, server.c
![Page 93: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/93.jpg)
System V IPC
IPC objects 信号量 (semaphore set) 消息队列 (message queue) 共享内存 (shared memory)
shell 命令 ipcs, ipcrm
![Page 94: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/94.jpg)
System V IPC 的共同特征 标识符与关键字
引用 IPC 对象:标识符 创建 IPC 对象时指定关键字 (key_t key;)
key 的选择;预定义常数 IPC_PRIVATE; ftok 函数 内核将关键字转换成标识符
许可权结构 和文件类比 struct ipc_perm
![Page 95: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/95.jpg)
SV IPC System Calls Overview
功能 消息队列 信号量 共享内存分配一个 IPC 对象,获得对 IPC 的访问
msgget semget shmget
IPC 操作 : 发送 / 接收消息,信号量操作,连接 /释放共享内存
msgsnd/msgrcv
semop shmat/shmdt
IPC 控制:获得 /修改状态信息,取消 IPC
msgctl semctl shmctl
![Page 96: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/96.jpg)
Semaphore
并发程序设计 互斥和同步 PV 操作 ( 原语 )
![Page 97: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/97.jpg)
PV 操作和信号量procedure p(var s:samephore){ s.value=s.value-1; if (s.value<0) asleep(s.queue); }
procedure v(var s:samephore){ s.value=s.value+1; if (s.value<=0) wakeup(s.queue); }
![Page 98: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/98.jpg)
Linux/UNIX 的信号量机制 semaphore set struct semid_ds
struct ipc_perm sem_perm; struct sem *sem_base; /* ptr to first sem in set */ time_t sem_otime; /* last operation time */ time_t sem_ctime; /* last change time */ ushort sem_nsems; /* count of sems in set */
![Page 99: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/99.jpg)
semaphore set system calls
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);int semop(int semid, struct sembuf *sops, unsigned nsops);int semctl(int semid, int semnum, int cmd, ...);
![Page 100: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/100.jpg)
semget: get a semaphore set identifier prototype
int semget(key_t key, int nsems, int semflg); “key” parameter
预定义常数 IPC_PRIVATE; 约定的关键字 ftok 函数
“semflg” parameter 设置访问权限 (低 9位 ) IPC_CREAT, IPC_EXCL 按位或
examples sem1.c
![Page 101: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/101.jpg)
semop: semaphore operations prototype
int semop(int semid, struct sembuf *sops, unsigned nsops); “sops” parameter
struct sembuf { unsigned short int sem_num; /* semaphore number */ short int sem_op; /* semaphore operation */ short int sem_flg; /* operation flag */}
examples: PV 操作的实现
![Page 102: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/102.jpg)
semctl: semaphore control operations prototype
int semctl(int semid, int semnum, int cmd, ...); the 4th argument
union semun{ int val; struct semid_ds *buf; unsigned short *array;} arg;
“cmd” parameter
![Page 103: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/103.jpg)
semctl: semaphore control operations (cont’d) “cmd” parameter
IPC_STAT: 对指定的信号量标识返回 arg.semid_ds结构中的当前值
IPC_SET: 在进程有足够权限的前提下,把信号量集合的当前关联值置为 arg.semid_ds结构给出的值
IPC_RMID: 删除信号量集合 SETVAL: 设置信号量集合中由 semnum 指定的单个
信号量的值 ( 设为 arg.val) examples
set_semvalue(初始化 ), del_semvalue(结束 )
![Page 104: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/104.jpg)
Examples
一个完整的实例 sem1.c( 进程互斥 )
![Page 105: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/105.jpg)
Home work:
用程序模拟实现生产者 /消费者问题 进程同步
![Page 106: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/106.jpg)
Message queue
消息队列 消息队列是消息的链表,存放在内核中并由消息队列标识符标识。
First in, first out message type: 优先级 块数据
struct msqid_ds
![Page 107: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/107.jpg)
message queue system calls
#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>
int msgget(key_t key, int size, int flag);int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);int msgctl(int msqid, int cmd, struct shmid_ds *buf);
![Page 108: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/108.jpg)
msgctl: message control operations prototype
int msgctl(int msqid, int cmd, struct shmid_ds *buf);
“cmd” parameter IPC_STAT: 把 msqid_ds结构中的数据置为消息队
列的当前关联值 IPC_SET: 在进程有足够权限的前提下,把消息队
列的当前关联值置为msqid_ds结构给出的值 IPC_RMID: 删除消息队列
![Page 109: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/109.jpg)
Example
A C/S application One server, several clients: only one
queue is required. Compared with FIFO implementation
![Page 110: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/110.jpg)
Shared memory
共享内存 共享内存是内核为进程创建的一个特殊内存
段,它可连接 (attach) 到自己的地址空间,也可以连接到其它进程的地址空间
最快的进程间通信方式 不提供任何同步功能
![Page 111: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/111.jpg)
shared memory system calls
#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>
int semget(key_t key, int size, int flag);void *shmat(int shmid, void *addr, int flag);int shmdt(void *addr);int shmctl(int shmid, int cmd, struct shmid_ds *buf);
![Page 112: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/112.jpg)
mmap/munmap system calls mmap/munmap: map or unmap files
or devices into memory
![Page 113: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/113.jpg)
6. Daemon process
什么是 daemon 进程 daemon 进程的实现方法
编程规则 出错记录
![Page 114: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/114.jpg)
What is a daemon?
![Page 115: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/115.jpg)
What is a daemon? (cont’d)
daemon 精灵进程或守护进程 后台执行 , 没有控制终端或登录 Shell 的进
程 why daemon?
![Page 116: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/116.jpg)
Concepts related to job control
Process group & session Controlling terminal jobs, fg, bg comands SIGINT, SIGQUIT, SIGTSTP, SIGHUP signal
s A solution the problem
nohup command & >> logfile
![Page 117: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/117.jpg)
daemon 进程的实现 (1) 编程规则
首先调用 fork ,然后使父进程 exit 调用 setsid创建一个新的会话期 将当前工作目录更改为特定目录 进程的 umask 设为 0 关闭不需要的文件描述符
![Page 118: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/118.jpg)
Exampleint daemon_init(void) {
pid_t pid;
if ( (pid = fork()) < 0)return(-1);
else if (pid != 0)exit(0); /* parent goes bye-bye */
/* child continues */setsid(); /* become session leader */chdir("/"); /* change working directory */umask(0); /* clear our file mode creation mask */
return(0);}
![Page 119: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/119.jpg)
daemon 进程的实现 (2) 出错记录
![Page 120: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/120.jpg)
7. Threads
What is a thread Basic pthread functions Thread synchronization Thread attributes Thread cancellation
![Page 121: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/121.jpg)
What is a thread?
Thread: A single flow of control within a process.
(susv3) Process and thread
New process: when a process executes a fork call, a new copy of the process is created with its own variables and its own PID.
New thread: When we create a new thread in a process, the new thread of execution gets its own stack (and hence local variables) but shares global variables, file descriptors, signal handlers, and its current directory state with the process that created it.
![Page 122: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/122.jpg)
Process and thread
![Page 123: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/123.jpg)
POSIX thread
POSIX1003.1c pthread library
/usr/lib/libpthread.so, /usr/lib/libpthread.a pthread.h header file
/usr/include/pthread.h Compiler options
gcc thread.c –o thread -lpthread
![Page 124: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/124.jpg)
Basic thread functions(1)
Create a new thread#include <pthread.h>int pthread_create(pthread_t *thread, pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg); Terminate the calling thread
void pthread_exit(void *retval);
![Page 125: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/125.jpg)
Basic thread functions(2)
Wait for termination of another thread#include <pthread.h>int pthread_join(pthread_t th, void **thread_return);
Put a running thread in the detached stateint pthread_detach(pthread_t th);
![Page 126: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/126.jpg)
Thread synchronization
用信号量进行同步 用互斥量进行同步 用条件变量进行同步
![Page 127: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/127.jpg)
POSIX4 semaphore
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_wait(sem_t *sem);int sem_post(sem_t *sem);int sem_destroy(sem_t *sem);
int sem_trywait(sem_t *sem);int sem_getvalue(sem_t *sem, int *sval);
![Page 128: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/128.jpg)
Example
Producer-consumer problem thread4.c, thread4a.c (in Ch11, BLP)
![Page 129: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/129.jpg)
Mutex (Mutual Exclusion)#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
![Page 130: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/130.jpg)
Example
thread5.c
![Page 131: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/131.jpg)
Thread attributes
线程属性对象 pthread_attr_t
初始化#include <pthread.h>int pthread_attr_init(pthread_attr_t *attr);
get/set族函数
![Page 132: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/132.jpg)
Get/Set thread attributes
#include <pthread.h>int pthread_attr_setdetachstate(pthread_attr_t *attr, int de
tachstate);int pthread_attr_getdetachstate(const pthread_attr_t *attr,
int *detachstate);int pthread_attr_setschedpolicy(pthread_attr_t *attr, int po
licy);int pthread_attr_getschedpolicy(const pthread_attr_t *attr,
int *policy);int pthread_attr_setschedparam(pthread_attr_t *attr, int p
aram);int pthread_attr_getschedparam(const pthread_attr_t *attr,
int *param);
![Page 133: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/133.jpg)
Example(1): 线程属性-分离线程 detachstate属性
Values: PTHREAD_CREATE_JOIN / PTHREAD_CREATE
_DETACHED thread6.c
![Page 134: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/134.jpg)
Example(2): 线程属性-调度 schedpolicy属性
调度策略 Values:
SCHED_OTHER/SCHED_RR/SCHED_FIFO schedparam属性
调度参数,主要是优先级 thread7a.c
![Page 135: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/135.jpg)
Thread cancellation
#include <pthread.h>int pthread_cancel(pthread_t thread);int pthread_setcancelstate(int state, int *oldstate);int pthread_setcanceltype(int type, int *oldtype);
![Page 136: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/136.jpg)
Multithread program
Examples: thread9.c, thread9a.c (in BLP)
![Page 137: Ch4 Linux System Programming – Process & IPC](https://reader036.fdocuments.in/reader036/viewer/2022081418/56814a18550346895db73e5f/html5/thumbnails/137.jpg)
Review