Слайд 2
Создание процессов
pid_t fork();
Слайд 3
Создание процессов
pid_t fork();
pid_t vfork();
Слайд 4
Создание процессов
pid_t fork();
pid_t vfork();
pid_t forkpty(int *amaster,
char *name,
const struct termios
*termp,
const struct winsize *winp);
Слайд 5
Слайд 6
Слайд 7
Слайд 8
Слайд 9
Слайд 10
Слайд 11
Слайд 12
Слайд 13
Слайд 14
Слайд 15
Атрибуты процесса
PID и PPID (Parent PID).
pid_t getpid();
pid_t getppid();
Слайд 16
Атрибуты процесса
PID и PPID (Parent PID).
pid_t getpid();
pid_t getppid();
// PID=1 для init.
//
Если родительский процесс завершается,
// потомок получает PPID=1.
Слайд 17
Атрибуты процесса
UID, GID, EUID, EGID.
// “Кто создал?”
// (Реальные идентификаторы пользователя и
группы).
uid_t getuid();
int setuid(uid_t uid);
gid_t getgid();
int setgid(gid_t gid);
// “От чьего лица выполняется?”
// (Эффективные идентификаторы пользователя и группы).
uid_t geteuid();
int seteuid(uid_t uid);
gid_t getegid();
int setegid(gid_t gid);
Слайд 18
Атрибуты процесса
Корневой каталог.
int chroot(const char *path);
// --- /var/new_root/somefile.txt
// --- chroot(“/var/new_root”);
// ---
/somefile.txt
Слайд 19
Атрибуты процесса
Рабочий каталог.
int chdir(const char *path);
int fchdir(int fd);
Слайд 20
Атрибуты процесса
Приоритет.
int nice(int incr);
// NZERO = 20
// NICE = 0..39
// NICE-20
Слайд 21
Атрибуты процесса
Ограничения.
int getrlimit(int resource, struct rlimit *rlp);
int setrlimit(int resource, const struct
rlimit *rlp);
struct rlimit {
rlim_t rlim_cur;
rlim_t rlim_max;
}
// RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE, RLIMIT_NOFILE, RLIMIT_STACK, RLIMIT_AS
// RLIM_SAVED_MAX, RLIM_SAVED_CUR, RLIM_INFINITY
Слайд 22
Атрибуты процесса
Ограничения.
long ulimit(int cmd, …); // Устаревший
int getrusage(int who, struct rusage
*r_usage);
// RUSAGE_SELF, RUSAGE_CHILDREN
int prlimit(pid_t pid,
int resource,
const struct rlimit *new_limit,
struct rlimit *old_limit);
Слайд 23
Атрибуты процесса
Переменные окружения.
extern char **environ;
// Имя=Значение
// Имя=Значение
// ...
// Имя=Значение
// \0
char *getenv(const
char *var);
int putenv(char *string);
int setenv(const char *var, const char *val, int overwrite);
int unsetenv(const char *var);
Слайд 24
Порождение процесов
Порождение процесса через exec.
int execl(const char *path, const char *arg,
...);
int execv(const char *path, char *const argv[]);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[]);
Слайд 25
Порождение процесов
Порождение процесса через exec.
int execl(const char *path, const char *arg,
...);
int execv(const char *path, char *const argv[]);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[]);
Слайд 26
Порождение процесов
Порождение процесса через exec.
int execl(const char *path, const char *arg,
...);
int execv(const char *path, char *const argv[]);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[]);
Слайд 27
Порождение процесов
Порождение процесса через exec.
int execl(const char *path, const char *arg,
...);
int execv(const char *path, char *const argv[]);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[]);
Слайд 28
Порождение процесов
Порождение процесса через exec.
int execl(const char *path, const char *arg,
...);
int execv(const char *path, char *const argv[]);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[]);
Слайд 29
Порождение процесов
Порождение процесса через system.
int system(const char *command);
Слайд 30
Ожидание потомка
Как предотвратить зомби?
pid_t waitpid(pid_t pid, int *statusp, int options);
// pid
<- PID или -1
// options <- WNOHANG
// wait(&status) = waitpid(-1, &status, 0);
Слайд 31
Исполнение процесса
Рождение
Слайд 32
Исполнение процесса
Рождение
Готовность
Слайд 33
Исполнение процесса
Рождение
Готовность
Выполнение
Ожидание
Слайд 34
Исполнение процесса
Рождение
Готовность
Выполнение
Ожидание
Смерть
Слайд 35
Слайд 36
Слайд 37
Сигналы
read(…)
SIGNAL
errno = EINTR
Слайд 38
Сигналы
Основые типы сигналов.
kill –l
SIGABRT
SIGALRM
SIGCHLD
SIGINT
SIGTERM
SIGKILL
SIGUSR1
SIGUSR2
SIGHUP
SIGRTMIN
SIGRTMAX
Слайд 39
Сигналы
ANSI C.
void handler(int signum)
{
// ...
}
// ANSI C
signal(SIGUSR1, handler);
signal(SIGUSR2, SIG_IGN);
signal(SIGTERM, SIG_DFL);
Слайд 40
Сигналы
POSIX.
// POSIX
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void
*);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}
Слайд 41
Сигналы
POSIX.
// POSIX
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void
*);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}
Слайд 42
Сигналы
POSIX.
// POSIX
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void
*);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
Слайд 43
Сигналы
POSIX.
// POSIX
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void
*);
sigset_t sa_mask;
int sa_flags; // SA_NODEFER, SA_RESETHAND, SA_SIGINFO, SA_RESTART
void (*sa_restorer)(void);
}
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
Слайд 44
Сигналы
POSIX.
// POSIX
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void
*);
sigset_t sa_mask;
int sa_flags; // SA_NODEFER, SA_RESETHAND, SA_SIGINFO, SA_RESTART
void (*sa_restorer)(void);
}
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
Слайд 45
Сигналы
siginfo_t.
union sigval {
int sival_int;
void *sival_ptr;
};
typedef struct {
int
si_signo;
int si_code; /* SI_USER, SI_KERNEL, SI_QUEUE, SI_TIMER */
union sigval si_value;
int si_errno;
pid_t si_pid;
uid_t si_uid;
void *si_addr;
int si_status;
int si_band;
} siginfo_t;
Слайд 46
Сигналы
Отправка и ожидание сигнала.
int kill(pid_t pid, int signum);
int sigqueue(pid_t pid, int
sig, const union sigval value);
int raise(int signum); // Синхронно.
int abort(); // SIGABRT
unsigned alarm(unsigned secs); // SIGALRM
int pause();
int sigwait(const sigset_t *set, int *signum);
Слайд 47
Сигналы
Безопасность.
volatile sig_atomic_t GlobalVariable;
Слайд 48
Слайд 49
Блокировка
File
PID
PID
PID
PID
PID
Слайд 50
Блокировка
File
PID
PID
PID
PID
PID
READ
WRITE
Слайд 51
Блокировка
File
PID
PID
PID
PID
PID
Exclusive lock
Exclusive lock
Слайд 52
Блокировка
File
PID
PID
PID
PID
PID
Слайд 53
Блокировка
File
PID
PID
PID
PID
PID
Слайд 54
Блокировка
File
PID
PID
PID
PID
PID
Слайд 55
Блокировка
File
PID
PID
PID
PID
PID
Exclusive lock
Exclusive lock
Exclusive lock
Exclusive lock
Слайд 56
Блокировка
File
PID
PID
PID
PID
PID
Exclusive lock
Exclusive lock
Exclusive lock
Exclusive lock
Слайд 57
Блокировка
File
PID
PID
PID
PID
PID
Exclusive lock
Exclusive lock
Exclusive lock
Exclusive lock
Слайд 58
Блокировка
File
PID
PID
PID
PID
PID
Shared lock
Shared lock
Shared lock
Exclusive lock
Слайд 59
Блокировка
Блокировки в коде.
flock(fd, LOCK_EX);
flock(fd, LOCK_SH);
flock(fd, LOCK_UN);
flock(fd, LOCK_EX | LOCK_NB);
flock(fd, LOCK_SH |
LOCK_NB);
Слайд 60
Файлы блокировок
Что мы хотим?
if(lock(“filename”))
{
// Какие-то действия
unlock(“filename”);
}
else
{
// ...
}
Слайд 61
Файлы блокировок
Реализация lock().
bool lock(char *filename)
{
int fd;
if(fd = open(filename, O_WRONLY
| O_CREATE | O_EXCL, 0)) == -1)
{
return false;
}
close(fd);
return true;
}
Слайд 62
Файлы блокировок
Реализация lock().
bool lock(char *filename)
{
int fd;
if(fd = open(filename, O_WRONLY
| O_CREATE | O_EXCL, 0)) == -1)
{
return false;
}
close(fd);
return true;
}
Слайд 63
Файлы блокировок
Реализация lock().
bool lock(char *filename)
{
int fd;
if(fd = open(filename, O_WRONLY
| O_CREATE | O_EXCL, 0)) == -1)
{
return false;
}
close(fd);
return true;
}
Слайд 64
Файлы блокировок
Реализация unlock().
bool unlock(char *filename)
{
unlink(filename);
return true;
}
Слайд 65
Общие смещения в файлах
Какой-то файл…
Слайд 66
Общие смещения в файлах
Какой-то файл…
Процесс 1
Слайд 67
Общие смещения в файлах
Какой-то файл…
Процесс 1
Слайд 68
Общие смещения в файлах
Какой-то файл…
Процесс 1
Слайд 69
Общие смещения в файлах
Какой-то файл…
Процесс 1
fd
Слайд 70
Общие смещения в файлах
Какой-то файл…
Процесс 1
fd
Процесс 2
fd
fork()
Слайд 71
Общие смещения в файлах
Какой-то файл…
Процесс 1
fd
Процесс 2
fd
fork()
Position
Слайд 72
Общие смещения в файлах
Какой-то файл…
Процесс 1
fd
Процесс 2
fd
fork()
Position
Слайд 73
Общие смещения в файлах
Какой-то файл…
Процесс 1
fd
Процесс 2
fd
fork()
Position
lseek(fd, NUMBER, SEEK_SET);
Слайд 74
Общие смещения в файлах
Какой-то файл…
Процесс 1
fd
Процесс 2
fd
fork()
Position
lseek(fd, NUMBER, SEEK_SET);
lseek(fd, 0, SEEK_CUR);
Слайд 75
Неименованные каналы
int pipe(int fd[2]);
Слайд 76
Неименованные каналы
fd[1] fd[0]
Слайд 77
Неименованные каналы
fd[1] fd[0]
Канал
Слайд 78
Неименованные каналы
fd[1] fd[0]
Канал
Слайд 79
Неименованные каналы
fd[1] fd[0]
Канал
Слайд 80
Неименованные каналы
fd[1] fd[0]
Канал
fd[1] fd[0]
Слайд 81
Неименованные каналы
fd[1] fd[0]
Канал
fd[1] fd[0]
Слайд 82
Неименованные каналы
fd[1] fd[0]
Канал
fd[1] fd[0]
Слайд 83
Неименованные каналы
fd[1] fd[0]
Канал
fd[1] fd[0]
Слайд 84
Неименованные каналы
fd[1] fd[0]
Канал
fd[1] fd[0]
Слайд 85
Неименованные каналы
Канал
Слайд 86
Неименованные каналы
Канал
PIPE_BUF
Слайд 87
Неименованные каналы
Канал
PIPE_BUF
long v = fpathconf(pfd[0], _PC_PIPE_BUF);
Слайд 88
Неименованные каналы
Пример конвейера.
who | sort | uniq | wc
Слайд 89
Неименованные каналы
who stdout
stdin sort stdout
stdin uniq stdout
stdin wc
Слайд 90
Неименованные каналы
who stdout
stdin sort stdout
stdin uniq stdout
stdin wc
Слайд 91
Неименованные каналы
who stdout
stdin sort stdout
stdin uniq stdout
stdin wc
Канал 1
Слайд 92
Неименованные каналы
who stdout
stdin sort stdout
stdin uniq stdout
stdin wc
Канал 1
Канал 2
Слайд 93
Неименованные каналы
who stdout
stdin sort stdout
stdin uniq stdout
stdin wc
Канал 1
Канал 2
Канал 3
Слайд 94
Неименованные каналы
Дублирование дескрипторов.
int dup(int oldfd);
int dup2(int oldfd, int newfd); // dup2(N,
N) = N
int dup3(int oldfd, int newfd, int flags /* O_CLOEXEC */);
Слайд 95
Неименованные каналы
Пример конвеера.
void who_wc() {
int pfd[2];
pipe(pfd);
if(!fork()) {
close(STDOUT_FILENO);
dup2(pfd[1], STDOUT_FILENO);
close(pfd[0]); close(pfd[1]);
execlp(“who”, “who”, NULL); }
if(!fork()) {
close(STDIN_FILENO);
dup2(pfd[0], STDIN_FILENO);
close(pfd[0]); close(pfd[1]);
execlp(“wc”, “wc”, “-l”, NULL); }
close(pfd[0]); close(pfd[1]);
wait(NULL); wait(NULL);
}
Слайд 96
Неименованные каналы
popen и pclose.
FILE *popen(const char *command, const char *type);
int
pclose(FILE *stream);
Слайд 97
Неименованные каналы
Двусторонние каналы.
int socketpair(int d, /* AF_UNIX */
int type,
int
protocol,
int sv[2]);
Слайд 98
Именованные каналы
FIFO.
int mkfifo(const char *path,
mode_t perms);