Слайд 1Многопоточное программирование
Дмитрий Калугин-Балашов
Лекция №5
Слайд 2IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 3IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 7SysV
SysV Object
id = const
id = const
Слайд 8SysV (ftok)
SysV Object
id = ftok(const char *pathname, int proj_id);
id = ftok(const
char *pathname, int proj_id);
Слайд 9SysV (ftok)
SysV Object
id = ftok(const char *pathname, int proj_id);
1
2
3
1
2
3
4
5
2
3
4
5
6
5
4
3
2
1
8
8
16
Слайд 10SysV (ipcs)
Вывод ipcs.
------ Shared Memory Segments --------
key shmid
owner perms bytes nattch status
------ Semaphore Arrays --------
key semid owner perms nsems
0x002fa327 0 root 666 2
------ Message Queues --------
key msqid owner perms used-bytes messages
Слайд 11SysV (ipcrm)
Использование ipcrm.
ipcrm –M shmkey
ipcrm –m shmid
ipcrm –Q msgley
ipcrm –q msgid
ipcrm
–s semkey
ipcrm –S semid
Слайд 12SysV (Права доступа)
Обладают идентификаторам пользователя и группы
Группы – означает создателя
Девять бит
– rwxrwxrwx
Бит x не имеет смысла
Слайд 13SysV (Права доступа)
ipc_perm.
struct ipc_perm {
uid_t uid;
gid_t gid;
uid_t cuid;
git_t cgid;
mode_t mode;
}
Слайд 14IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 16IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 17IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 18Очереди сообщений (SysV)
int msgget(key_t key, int flags);
ftok(…);
IPC_CREAT
O_CREAT
IPC_CREAT
Слайд 19Очереди сообщений (SysV)
int msgget(key_t key, int flags);
ftok(…);
IPC_CREAT
O_CREAT
IPC_CREAT
IPC_PRIVATE
Слайд 20Очереди сообщений (SysV)
msgctl.
int msgctl(int msgq,
int cmd /* IPC_SET, IPC_STAT,
IPC_RMID */,
struct msqid_ds *data);
struct msqid_ds {
struct ipc_perm msg_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode;
}
msgqnum_t msg_qnum;
msglen_t msg_qbytes;
pid_t msg_lspid, msg_lrpid;
time_t msg_stime, msg_rtime, msg_ctime;
}
Слайд 21Очереди сообщений (SysV)
msgsnd/msgrcv.
int msgsnd(int msgid,
const void *msgp,
size_t
msgsz,
int msgflg);
int msgrcv(int msgid,
void *msgp,
size_t msgsz,
long msgtyp,
int msgflg);
struct msg {
long mtype;
char mtext[MTEXTSIZE];
}
Слайд 22Очереди сообщений (SysV)
msgsnd/msgrcv.
int msgsnd(int msgid,
const void *msgp,
size_t
msgsz,
int msgflg);
int msgrcv(int msgid,
void *msgp,
size_t msgsz,
long msgtyp,
int msgflg);
struct msg {
long mtype;
char mtext[MTEXTSIZE];
}
Слайд 23Очереди сообщений (SysV)
msgsnd/msgrcv.
int msgsnd(int msgid,
const void *msgp,
size_t
msgsz,
int msgflg);
int msgrcv(int msgid,
void *msgp,
size_t msgsz,
long msgtyp,
/* ‘=0’ – Any, ‘>0’ – Current, ‘<0’ - <= abs(Current) */
int msgflg);
struct msg {
long mtype; // Not 0
char mtext[MTEXTSIZE];
}
Слайд 24Очереди сообщений (SysV)
msgsnd/msgrcv.
int msgsnd(int msgid,
const void *msgp,
size_t
msgsz,
int msgflg);
int msgrcv(int msgid,
void *msgp,
size_t msgsz,
long msgtyp,
/* ‘=0’ – Any, ‘>0’ – Current, ‘<0’ - <= abs(Current) */
int msgflg); // MSG_NOERROR, IPC_NOWAIT => EAGAIN
struct msg {
long mtype; // Not 0
char mtext[MTEXTSIZE];
}
Слайд 25IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 26Очереди сообщений (POSIX)
mq_open.
mqd_t mq_open(const char *name,
int flags);
// O_RDONLY, O_WRONLY,
O_RDWR, O_NONBLOCK
mqd_t mq_open(const char *name,
int flags,
mode_t perms,
struct mq_attr *attr);
// + O_CREAT, O_EXCL
int mq_getattr(mqd_t mqd,
struct mq_attr *attr);
int mq_setattr(mqd_t mqd,
const struct mq_attr *attr,
struct mq_attr *oldattr);
Слайд 27Очереди сообщений (POSIX)
mq_attr.
struct mq_attr {
long mq_flags;
long mq_maxmsg;
long mq_msgsize;
long mq_curmsg;
}
Слайд 28Очереди сообщений (POSIX)
mq_close/mq_unlink.
int mq_close(mqd_t mqd);
int mq_unlink(const char *name);
Слайд 29Очереди сообщений (POSIX)
mq_send/mq_receive.
int mq_send(mqd_t mqd,
const char *msg,
size_t
msgsize,
unsigned priority /* 0..31..> */);
ssize_t mq_receive(mqd_t mqd,
char *msg,
size_t msgsize,
unsigned *priorityp);
Слайд 30Очереди сообщений (POSIX)
mq_timedsend/mq_timedreceive.
int mq_timedsend(mqd_t mqd,
const char *msg,
size_t
msgsize,
unsigned priority,
const struct timespec *tmout);
ssize_t mq_timedreceive(mqd_t mqd,
char *msg,
size_t msgsize,
unsigned *prtorityp,
const struct timespec *tmout);
Слайд 31Очереди сообщений (POSIX)
mq_notify.
int mq_notify(
mqd_t mqd,
const struct sigevent
*ep);
// 1. После вызова mq_notify: извлечь все сообщения из очереди (O_NONBLOCK).
// 2. После прибытия сигнала: Вызвать mq_notify и выполнить (1).
Слайд 32IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 33IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 34Семафоры (POSIX)
semget.
int semget(key_t key, int nsems, int flags);
Слайд 35Семафоры (POSIX)
semctl.
int semctl(int semid, int semnum, int cmd, union semun arg);
Слайд 36Семафоры (POSIX)
semctl.
int semctl(int semid, int semnum, int cmd, union semun arg);
union
semun { int val; struct semid_ds *buf; unsigned short *array; }
Слайд 37Семафоры (POSIX)
semctl.
int semctl(int semid, int semnum, int cmd, union semun arg);
union
semun { int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
Слайд 38Семафоры (POSIX)
semctl.
int semctl(int semid, int semnum, int cmd, union semun arg);
union
semun { int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
Слайд 39Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, int cmd, union semun arg);
union
semun { int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
Слайд 40Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, int cmd, union semun arg);
union
semun { int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
Слайд 41Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, IPC_RMID, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
Слайд 42Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, IPC_STAT, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
Слайд 43Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, IPC_SET, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
Слайд 44Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, GETNCNT, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
// Получить количество процессов, ожидающих увеличения значения семафора.
Слайд 45Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, GETZCNT, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
// Получить количество процессов, ожидающих, пока значение семафора не достигнет нуля.
Слайд 46Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, GETPID, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
// Получить PID последнего, обратившегося в semop, процесса.
Слайд 47Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, GETVAL, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
// Получить значение семафора.
Слайд 48Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, SETVAL, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
// Установить значение семафора.
Слайд 49Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, GETALL, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
// Получить значение всех семафоров.
Слайд 50Семафоры (SysV)
semctl.
int semctl(int semid, int semnum, SETALL, union semun arg);
union semun
{ int val; struct semid_ds *buf; unsigned short *array; }
struct semid_ds {
struct ipc_perm sem_perm;
unsigned short sem_nsems;
time_t sem_otime; time_t sem_ctime; }
struct ipc_perm {
uid_t uid; gid_t gid;
uid_t cuid; git_t cgid;
mode_t mode; }
// Установить значение всех семафоров.
Слайд 51Семафоры (SysV)
semop.
int semop(int semid, struct sembuf *sops, size_t nsops);
struct sembuf {
unsigned short sem_num;
short sem_op;
short sem_flg; }
sem_op > 0 – добавляем semop к значению семафора
sem_op < 0 – ждем, пока значение семафора меньше |sem_op|, потом его вычитаем
sem_op = 0 – ждем, пока значением семафора не 0
IPC_NOWAIT
IPC_UNDO
Слайд 52IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 53Семафоры (POSIX)
sem_open/sem_close/sem_unlink.
sem_t *sem_open(const char *name, int flags);
sem_t *sem_open(const char *name,
int flags,
mode_t perms,
unsigned value);
int sem_close(sem_t *sem);
int sem_unlink(const char *name);
Слайд 54Семафоры (POSIX)
Работа с семафором.
int sem_post(sem_t *sem); // +1
int sem_wait(sem_t *sem); //
-1
int sem_trywait(sem_t *sem); // Like O_NONBLOCK or IPC_NOWAIT
int sem_timedwait(sem_t *restrict sem,
const struct timespec *time);
int sem_getvalue(sem_t *restrict sem,
int *valuep);
Слайд 55IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 56Семафоры (POSIX)
sem_init/sem_destroy.
int sem_init(sem_t *sem, int pshared, unsigned value);
int sem_destroy(sem_t *sem);
Слайд 57IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 58IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 59Общая память (SysV)
Создание и управление.
int shmget(key_t key, size_t size, int flags);
int
shmctl(int shmid, int cmd, struct shmid_ds *data);
struct shmid_ds {
struct ipc_perm shm_perm;
size_t shm_segsz;
pid_t shm_lpid;
pid_t shm_cpid;
shmatt_t shm_nattch;
time_t shm_atime;
time_t shm_dtime;
time_t shm_ctime; }
Слайд 60Общая память (SysV)
Присоединение и отсоединение.
void *shmat(int shmid,
const void *shmaddr
/* EINVAL */,
int flags /* SHM_RND, SHM_RDONLY */);
int shmdt(const void *shmaddr);
Слайд 61IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 62Отображение файлов в память
mmap/munmap.
void *mmap(
void *addr,
size_t len,
int prot, // PROT_NONE, PROT_READ, PROT_WRITE, PROT_EXEC
int flags, // MAP_PRIVATE, MAP_SHARED, MAP_FIXED, MAP_ANONYMOUS
int fd,
off_t off);
int munmap(
void *addr,
size_t len);
Слайд 63IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 64Отображение файлов в память
shm_open/shm_unlink.
int shm_open(
const char *name,
int
flags,
mod_t perms
);
int ftruncate(int fd, off_t length);
shm_unlink(const char *name);
Слайд 65IPC
Очереди сообщений
Семафоры
Общая память
POSIX
SysV
msgget
msgctl
msgsnd
msgrcv
mq_open
mq_close
mq_unlink
mq_send
mq_receive
…
semget
semctl
semop
sem_open
sem_close
sem_unlink
sem_wait
sem_post
…
sem_init
sem_destroy
shmget
shmctl
shmat
shmdt
shm_open
shm_unlink
mmap
munmap
…
Слайд 66Таймеры
Будильник.
unsigned alarm(unsigned secs);
Слайд 67Таймеры
Сон.
unsigned sleep(unsigned secs);
unsigned usleep(useconds_t usecs);
unsigned nanosleep(const struct timespec *nsecs,
struct
timespec *remain);
tv_sec
tv_nsec
Слайд 68Таймеры
Виды таймеров.
ITIMER_REAL – реальное время, SIGALRM
ITIMER_VIRTUAL – виртуальное время, SIGVTALRM
ITIMER_PROF –
время работы в процессе + время работы в ядре от имени процесса, SIGPROF
int getitimer(int which, struct itimerval *val);
int settimer(int which, const struct itimerval *val,
struct itimerval *oval);
struct itimerval { struct timeval it_interval, it_value);
Слайд 70Передача дескрипторов
sendmsg/recvmsg.
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
ssize_t recvmsg(int
sockfd, struct msghdr *msg, int flags);
struct iovec {
void *iov_base;
size_t iov_len;
};
struct msghdr {
void *msg_name;
socklen_t msg_namelen;
struct iovec *msg_iov;
size_t msg_iovlen;
void *msg_control;
size_t msg_controllen;
int msg_flags;
};
Слайд 71Передача дескрипторов
cmsghdr.
struct cmsghdr {
socklen_t cmsg_len; /* счетчик байтов данных
с заголовком */
int cmsg_level; /* создаваемый протокол передачи */
int cmsg_type; /* тип, зависящий от протокола */
/* с последующей переменной без знакаc msg_data[]; */
};
Слайд 72Передача дескрипторов
Макросы.
struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh, struct
cmsghdr *cmsg);
size_t CMSG_ALIGN(size_t length);
size_t CMSG_SPACE(size_t length);
size_t CMSG_LEN(size_t length);
unsigned char *CMSG_DATA(struct cmsghdr *cmsg);
Слайд 73Передача дескрипторов
Пример.
http://keithp.com/blogs/fd-passing/
Слайд 74Реализовать в web-сервере возможность параллельного исполнения запросов (с помощью воркеров -
дочерних процессов или потоков)
Добавить в параметры сервера опцию –w – число воркеров.
Воркеры должны нагружаться равномерно (можно проверить с помощью нагрузочного теста).
Парсинг параметров не должен быть ручным (можно использовать getopt)
Логи необходимо писать в syslog.
2
Последнее занятие