2023.11.16 TIL
Code, Image source: The Linux Programming Interface, Michael Kerrisk
Named Semaphores
Unnamed Semaphores
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
sem_t *sem_open(const char *name, int oflag, ... /* mode_t mode, unsigned int value*/ );
SEM_FAILED
on errortlpi-dist/psem/psem_create.c
#include <semaphore.h>
int sem_close(sem_t *sem);
#include <semaphore.h>
int sem_unlink(const char *name);
sem_post()
#include <semaphore.h>
int sem_wait(sem_t *sem);
tlpi-dist/psem/psem_post.c
sem_wait()
#include <semaphore.h>
int sem_post(sem_t *sem);
tlpi-dist/psem/psem_wait.c
$ ./psem_create -c /demo 600 0
$ ./psem_wait /demo & # 0이니까 기다림
[1] 31208
$ ./psem_getvalue /demo
0
$ ./psem_post /demo
$ 31208 sem_wait() succedded # 1로 변해서 wakeup, 돌아감
Press Enter
[1]- Done ./psem_wait /demo
$ ./psem_post /demo
$ ./psem_getvalue /demo
1
$ ./psem_unlink /demo
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
pshared
: 공유변수, 0이면 thread간 공유, 1이면 process fork해서 공유
tlpi-dist/psem/thread_incr_psem.c
#include <semaphore.h>
int sem_destroy(sem_t *sem);
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
int shm_open(const char *name, int oflag, mode_t mode);
oflag
O_CREAT
: Create object if it doesn’t already existO_EXCL
: With O_CREAT, create object exclusivelyO_RDONLY
: Open for read-only accessO_RDWR
: Open for read-write accessO_TRUNC
: Truncate object to zero lengthtlpi-dist/pshm/pshm_create.c
tlpi-dist/pshm/pshm_write.c
tlpi-dist/pshm/pshm_read.c
$ ./pshm_create -c /demo_shm 0
$ ls -l /dev/shm
total 4
-rw------- 1 mtk users 0 Jun 21 13:33 demo_shm
$ ./pshm_write /demo_shm 'hello'
$ ls -l /dev/shm
total 4
-rw------- 1 mtk users 5 Jun 21 13:33 demo_shm # size 5byte 증가
$ ./pshm_read /demo_shm
hello
tlpi-dist/svipc/svmsg_demo_server.c
#define KEY_FILE "/some-path/some-file"
key = ftok(KEY_FILE, 1);
$ ipcs
→ System의 전반적인 key값 조회(key, shmid, owner, perms, bytes, ...)$ ipcrm -X key
→ key로 지우기$ ipcrm -x id
→ id로 지우기#include <sys/types.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
#include <sys/types.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ... /* union semun arg */ );
#include <sys/types.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned int nsops);
$ ./svsem_demo 0 # Semaphore를 0으로 생성
Semaphore ID = 98307
$ ./svsem_demo 98307 -2 & # 0보다 작으니까 대기
23338: about to semop at 10:19:42
[1] 23338
$ ./svsem_demo 98307 +3 # wakeup
23339: about to semop at 10:19:55
23339: semop completed at 10:19:55
23338: semop completed at 10:19:55
[1]+ Done ./semop_demo98307 -2
tlpi-dist/svsem_demo.c
tlpi-dist/svsem/binary_sems.h
tlpi-dist/svsem/binary_sems.c
#include <sys/types.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
#include <sys/types.h>
#include <sys/shm.h>
int *shmat(int shmid, const void *shmaddr, int shmflg);
#include <sys/types.h>
#include <sys/shm.h>
int semop(const void *shmaddr);
shmctl(int id, IPC_RMID, int flag)
$ wc -c /etc/services # Display size of test file
764360 /etc/services
$ ./svshm_xfr_writer < /etc/services &
[1] 9403
$ ./svshm_xfr_reader > out.txt
Received 764360 bytes (747 xfrs) # message from reader
Sent 764360 bytes (747 xfrs) # message from writer
[1]+ Done ./svshm_xfr_writer < /etc/services
$ diff /etc/services out.txt
tlpi-dist/svshm_xfr.h
→ key는 그냥 여기서 한거처럼 하드코딩 (0x1234
, 0x5678
)tlpi-dist/svshm/svshm_xfr_writer.c
tlpi-dist/svshm/svshm_xfr_reader.c
$ cat /proc/[PID]/maps