[태그:] linux

  • raspberry pi4 커널 컴파일

    삼국지도 다 끝났고, 남는 시간에 리눅스 커널을 배워 보기로 했다. 시간 남을 땐 이게 효과가 확실하지. 전에 샀던 “디버깅을 통해 배우는 리눅스 커널의 구조와 원리”를 따라 해보기로 했다. 커널이 리눅스 심장과 같아 꼭 배울 필요는 없지만, 알면 편하게 살 수 있다. 리눅스 역시 과거 서버를 벗어나 arm에 로딩되어 여러 임베디드 리눅스로 사용되고 있다. 라즈베리 파이 역시 미친 가격으로 집에서 누구나 쉽게 구할 수 있다. 지금 IoT가 뜨고 있는데 안 배울 이유가 없다.

    책에 나온 커널이 버전 4.19다. 2021. 5월 업데이트를 하면 커널 5.10을 사용한다. 일단 커널을 4.19 버전으로 강제로 맞춰야 한다.

    pi@raspberrypi:~ $ uname -a
    Linux raspberrypi 5.10.17-v7l+ #1414 SMP Fri Apr 30 13:20:47 BST 2021 armv7l GNU/Linux

    책 53 페이지에 나온대로 따라했다. 15년전에 비하면 정말 편해졌다. 그 때 컴파일 옵션이 너무 많아 하드웨어 지식이 없어 무엇을 선택할 지 몰랐다.

    #https://www.raspberrypi.org/documentation/linux/kernel/building.md
    
    #필요 모듈 설치.
    sudo apt install git bc bison flex libssl-dev make
    
    git clone --depth=1 --branch rpi-4.19.y https://github.com/raspberrypi/linux
    
    cd linux
    #KERNEL=kernel7
    KERNEL=kernel7l
    #make bcm2709_defconfig
    make bcm2711_defconfig

    책은 make bcm2709_defconfig로 컴파일 옵션을 설정했다. 아무 생각없이 따라하다 보면 usb를 하나도 인식하지 못하는 현상을 겪는다.

    pi@raspberrypi:~ $ lsusb
    pi@raspberrypi:~ $

    이거 때문에 한동안 고민했다. make menu로 usb를 설정하는 옵션을 찾아 켜주면 될 듯 한데, 내가 많이 몰라 다른 옵션을 어떻게 설정할지 판단 못하겠다. 옵션 하나 켜겠다고 그 짓을 해야되나… usb가 막혀 키보드도 연결되지 않고, usb 메모리, 카메라 등 아무것도 연결되지 않았다. usb 4포트가 모두 불량인 줄 알고 환불할 뻔 했다.

    pi@raspberrypi:~ $ cat /proc/cpuinfo
    processor	: 0
    model name	: ARMv7 Processor rev 3 (v7l)
    BogoMIPS	: 270.00
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd08
    CPU revision	: 3
    
    processor	: 1
    model name	: ARMv7 Processor rev 3 (v7l)
    BogoMIPS	: 270.00
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd08
    CPU revision	: 3
    
    processor	: 2
    model name	: ARMv7 Processor rev 3 (v7l)
    BogoMIPS	: 270.00
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd08
    CPU revision	: 3
    
    processor	: 3
    model name	: ARMv7 Processor rev 3 (v7l)
    BogoMIPS	: 270.00
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd08
    CPU revision	: 3
    
    Hardware	: BCM2711
    Revision	: b03114
    Serial		: 100000003d82cd51
    Model		: Raspberry Pi 4 Model B Rev 1.4
    

    책에 없지만, 웹 사이트와 여기 보드 정보를 보면 bcm2711을 사용했다. 이 옵션이 맞다. 이게 customized 제품과 대량 생산품 차이다. 이 옵션을 개인이 일일히 다 넣어주려면 힘들겠다. 표준화된 하드웨어를 사용함이 훨씬 낫다. 아무리 많이 판대도 raspberry pi 만큼 팔릴 수 있을 지 모르겠다. 단가에서 경쟁하기 어렵다고 본다.

    make -j4 zImage modules dtbs
    sudo make modules_install
    sudo cp arch/arm/boot/dts/*.dtb /boot/
    sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
    sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
    sudo cp arch/arm/boot/zImage /boot/$KERNEL.img

    나머지를 실행한다. boot 디렉토리 파일을 덮어쓰기 전에 기존 파일을 꼭 백업해야 한다. 그냥 날려 버리면 나처럼 다시 이미지를 구워야 한다.

    pi@raspberrypi:~ $ lsusb
    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    pi@raspberrypi:~ $ uname -a
    Linux raspberrypi 4.19.127-v7l+ #2 SMP Thu May 13 15:17:29 BST 2021 armv7l GNU/Linux

    1.5시간 컴파일 후 정상적으로 부팅했음을 확인했다.

    cross compile을 하기로 했다. 1.5 시간이 10분으로 줄어드는 마법을 보았다. https://www.raspberrypi.org/documentation/linux/kernel/building.md 사이트에 가면 cross compile 하는 방법이 나와 있다. 그대로 따라하면 된다.

    /boot 디렉토리 내용을 통째로 날렸는데, 그러면 안된다. start.elf 파일이 없다고 부팅되지 않는다.

    pi@raspberrypi:/boot $ ls -l
    total 27721
    -rwxr-xr-x 1 root root   24270 May 15  2021 bcm2708-rpi-b-plus.dtb
    -rwxr-xr-x 1 root root   24007 May 15  2021 bcm2708-rpi-b.dtb
    -rwxr-xr-x 1 root root   23788 May 15  2021 bcm2708-rpi-cm.dtb
    -rwxr-xr-x 1 root root   24448 May 15  2021 bcm2708-rpi-zero-w.dtb
    -rwxr-xr-x 1 root root   23712 May 15  2021 bcm2708-rpi-zero.dtb
    -rwxr-xr-x 1 root root   25334 May 15  2021 bcm2709-rpi-2-b.dtb
    -rwxr-xr-x 1 root root   25483 May 15  2021 bcm2710-rpi-2-b.dtb
    -rwxr-xr-x 1 root root   27143 May 15  2021 bcm2710-rpi-3-b-plus.dtb
    -rwxr-xr-x 1 root root   26524 May 15  2021 bcm2710-rpi-3-b.dtb
    -rwxr-xr-x 1 root root   25338 May 15  2021 bcm2710-rpi-cm3.dtb
    -rwxr-xr-x 1 root root   41185 May 15  2021 bcm2711-rpi-4-b.dtb
    -rwxr-xr-x 1 root root   18695 May 15  2021 bcm2835-rpi-a-plus.dtb
    -rwxr-xr-x 1 root root   18579 May 15  2021 bcm2835-rpi-a.dtb
    -rwxr-xr-x 1 root root   18982 May 15  2021 bcm2835-rpi-b-plus.dtb
    -rwxr-xr-x 1 root root   18858 May 15  2021 bcm2835-rpi-b-rev2.dtb
    -rwxr-xr-x 1 root root   18725 May 15  2021 bcm2835-rpi-b.dtb
    -rwxr-xr-x 1 root root   18690 May 15  2021 bcm2835-rpi-cm1-io1.dtb
    -rwxr-xr-x 1 root root   19173 May 15  2021 bcm2835-rpi-zero-w.dtb
    -rwxr-xr-x 1 root root   18647 May 15  2021 bcm2835-rpi-zero.dtb
    -rwxr-xr-x 1 root root   19558 May 15  2021 bcm2836-rpi-2-b.dtb
    -rwxr-xr-x 1 root root   21027 May 15  2021 bcm2837-rpi-3-b-plus.dtb
    -rwxr-xr-x 1 root root   20238 May 15  2021 bcm2837-rpi-3-b.dtb
    -rwxr-xr-x 1 root root   52456 May 15  2021 bootcode.bin
    -rwxr-xr-x 1 root root     121 May 15  2021 cmdline.txt
    -rwxr-xr-x 1 root root    1809 May 15  2021 config.txt
    -rwxr-xr-x 1 root root    7314 May 15  2021 fixup.dat
    -rwxr-xr-x 1 root root    5446 May 15  2021 fixup4.dat
    -rwxr-xr-x 1 root root    3191 May 15  2021 fixup4cd.dat
    -rwxr-xr-x 1 root root    8454 May 15  2021 fixup4db.dat
    -rwxr-xr-x 1 root root    8452 May 15  2021 fixup4x.dat
    -rwxr-xr-x 1 root root    3191 May 15  2021 fixup_cd.dat
    -rwxr-xr-x 1 root root   10298 May 15  2021 fixup_db.dat
    -rwxr-xr-x 1 root root   10298 May 15  2021 fixup_x.dat
    -rwxr-xr-x 1 root root     145 May 15  2021 issue.txt
    -rwxr-xr-x 1 root root 5773448 May 15  2021 kernel7l.img
    drwxr-xr-x 2 root root   16384 May 15  2021 overlays
    -rwxr-xr-x 1 root root 2952928 May 15  2021 start.elf
    -rwxr-xr-x 1 root root 2228768 May 15  2021 start4.elf
    -rwxr-xr-x 1 root root  793084 May 15  2021 start4cd.elf
    -rwxr-xr-x 1 root root 3722504 May 15  2021 start4db.elf
    -rwxr-xr-x 1 root root 2981160 May 15  2021 start4x.elf
    -rwxr-xr-x 1 root root  793084 May 15  2021 start_cd.elf
    -rwxr-xr-x 1 root root 4794472 May 15  2021 start_db.elf
    -rwxr-xr-x 1 root root 3704712 May 15  2021 start_x.elf
    

    overlays 내용을 날리고, 새로 컴파일 버전으로 설치했고, start.elf, *.dat, bootcode.bin, *.txt를 전에 받았던 백업에서 복사했다. 다행히 잘 된다. 두 번은 하지만, 세 번은 못 하겠다. 책이 왜 스크립트를 설명했는지 이해된다.

  • fork bomb

    fork로 주기적으로 exec를 하는 방법을 알아보고 있었다. 잘못하여 이렇게 썼다.

    while(1){
        fork();
    }

    이런 **ㄹ!#ㄲㄴㅇㄹㅉㅆㄲ$!!!! 게다가 sudo로 실행했다. ssh, ping 등 명령어에 응답하지 않는다. 하드웨어에 접근할 수 없었는데, 다행히 crontab에 등록한 재부팅 명령어는 동작했다.

  • posix shared memory, p325~p335

    fork로 나온 parent, child와 다르게 완전 다른 프로세스간 shared memory로 데이터를 공유할 수 있다.

    pi@raspberrypi:~/Project/cCode/IPC/shared_memory $ cat make_memory.c 
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <semaphore.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #define FILE_MODE 0666
    
    int
    main(int argc, char **argv)
    {
    	int		c, fd, flags;
    	char	*ptr;
    	off_t	length;
    
    	flags = O_RDWR | O_CREAT;
    	while ( (c = getopt(argc, argv, "e")) != -1) {
    		switch (c) {
    		case 'e':
    			flags |= O_EXCL;
    			break;
    		}
    	}
    	if (optind != argc - 2)
    		perror("usage: shmcreate [ -e ] <name> <length>");
    	length = atoi(argv[optind + 1]);
    
    	fd = shm_open(argv[optind], flags, FILE_MODE);
    	ftruncate(fd, length);
    
    	ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    
    	exit(0);
    }
    pi@raspberrypi:~/Project/cCode/IPC/shared_memory $ cat unlink.c 
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <semaphore.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #define FILE_MODE 0666
    
    
    
    int
    main(int argc, char **argv)
    {
    	if (argc != 2)
    		perror("usage: shmunlink <name>");
    
    	shm_unlink(argv[1]);
    
    	exit(0);
    }
    pi@raspberrypi:~/Project/cCode/IPC/shared_memory $ cat write.c 
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <semaphore.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #define FILE_MODE 0666
    
    int
    main(int argc, char **argv)
    {
    	int		i, fd;
    	struct stat	stat;
    	unsigned char	*ptr;
    
    	if (argc != 2)
    		perror("usage: shmwrite <name>");
    
    		/* 4open, get size, map */
    	fd = shm_open(argv[1], O_RDWR, FILE_MODE);
    	fstat(fd, &stat);
    	ptr = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE,
    			   MAP_SHARED, fd, 0);
    	close(fd);
    
    		/* 4set: ptr[0] = 0, ptr[1] = 1, etc. */
    	for (i = 0; i < stat.st_size; i++)
    		*ptr++ = i % 256;
    
    	exit(0);
    }
    pi@raspberrypi:~/Project/cCode/IPC/shared_memory $ cat read.c 
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <semaphore.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #define FILE_MODE 0400
    
    int
    main(int argc, char **argv)
    {
    	int		i, fd;
    	struct stat	stat;
    	unsigned char	c, *ptr;
    
    	if (argc != 2)
    		perror("usage: shmread <name>");
    
    		/* 4open, get size, map */
    	fd = shm_open(argv[1], O_RDONLY, FILE_MODE);
    	fstat(fd, &stat);
    	ptr = mmap(NULL, stat.st_size, PROT_READ,
    			   MAP_SHARED, fd, 0);
    	close(fd);
    
    		/* 4check that ptr[0] = 0, ptr[1] = 1, etc. */
    	for (i = 0; i < stat.st_size; i++)
    		if ( (c = *ptr++) == (i % 256))
    			printf("ptr[%d] = %d\n", i, c);
    
    	exit(0);
    }

    이를 실행하면 다음과 같다. 512 길이 메모리를 할당하고, 250~259번지를 보면 다시 0으로 돌아간다. od로 확인하면 255에서 0으로 갔음을 본다. 파일 사용하는 방법과 비슷하다.

    pi@raspberrypi:~/Project/cCode/IPC/shared_memory $ ./makemeory test 512
    pi@raspberrypi:~/Project/cCode/IPC/shared_memory $ ./write test
    pi@raspberrypi:~/Project/cCode/IPC/shared_memory $ od -A d -t u1 -t x2 /dev/shm/test 
    0000000   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
               0100    0302    0504    0706    0908    0b0a    0d0c    0f0e
    0000016  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
               1110    1312    1514    1716    1918    1b1a    1d1c    1f1e
    0000032  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47
               2120    2322    2524    2726    2928    2b2a    2d2c    2f2e
    0000048  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63
               3130    3332    3534    3736    3938    3b3a    3d3c    3f3e
    0000064  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79
               4140    4342    4544    4746    4948    4b4a    4d4c    4f4e
    0000080  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95
               5150    5352    5554    5756    5958    5b5a    5d5c    5f5e
    0000096  96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111
               6160    6362    6564    6766    6968    6b6a    6d6c    6f6e
    0000112 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
               7170    7372    7574    7776    7978    7b7a    7d7c    7f7e
    0000128 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
               8180    8382    8584    8786    8988    8b8a    8d8c    8f8e
    0000144 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
               9190    9392    9594    9796    9998    9b9a    9d9c    9f9e
    0000160 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
               a1a0    a3a2    a5a4    a7a6    a9a8    abaa    adac    afae
    0000176 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
               b1b0    b3b2    b5b4    b7b6    b9b8    bbba    bdbc    bfbe
    0000192 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
               c1c0    c3c2    c5c4    c7c6    c9c8    cbca    cdcc    cfce
    0000208 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
               d1d0    d3d2    d5d4    d7d6    d9d8    dbda    dddc    dfde
    0000224 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
               e1e0    e3e2    e5e4    e7e6    e9e8    ebea    edec    efee
    0000240 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
               f1f0    f3f2    f5f4    f7f6    f9f8    fbfa    fdfc    fffe
    0000256   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
               0100    0302    0504    0706    0908    0b0a    0d0c    0f0e
    0000272  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
               1110    1312    1514    1716    1918    1b1a    1d1c    1f1e
    0000288  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47
               2120    2322    2524    2726    2928    2b2a    2d2c    2f2e
    0000304  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63
               3130    3332    3534    3736    3938    3b3a    3d3c    3f3e
    0000320  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79
               4140    4342    4544    4746    4948    4b4a    4d4c    4f4e
    0000336  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95
               5150    5352    5554    5756    5958    5b5a    5d5c    5f5e
    0000352  96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111
               6160    6362    6564    6766    6968    6b6a    6d6c    6f6e
    0000368 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
               7170    7372    7574    7776    7978    7b7a    7d7c    7f7e
    0000384 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
               8180    8382    8584    8786    8988    8b8a    8d8c    8f8e
    0000400 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
               9190    9392    9594    9796    9998    9b9a    9d9c    9f9e
    0000416 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
               a1a0    a3a2    a5a4    a7a6    a9a8    abaa    adac    afae
    0000432 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
               b1b0    b3b2    b5b4    b7b6    b9b8    bbba    bdbc    bfbe
    0000448 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
               c1c0    c3c2    c5c4    c7c6    c9c8    cbca    cdcc    cfce
    0000464 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
               d1d0    d3d2    d5d4    d7d6    d9d8    dbda    dddc    dfde
    0000480 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
               e1e0    e3e2    e5e4    e7e6    e9e8    ebea    edec    efee
    0000496 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
               f1f0    f3f2    f5f4    f7f6    f9f8    fbfa    fdfc    fffe
    0000512
    pi@raspberrypi:~/Project/cCode/IPC/shared_memory $ ./read test | grep -e "ptr\[25[0-9]\]"
    ptr[250] = 250
    ptr[251] = 251
    ptr[252] = 252
    ptr[253] = 253
    ptr[254] = 254
    ptr[255] = 255
    ptr[256] = 0
    ptr[257] = 1
    ptr[258] = 2
    ptr[259] = 3
  • shared memory introduction, p303 ~ p315

    semaphore로 process간 데이터를 주고 받을 줄 알았는데, 아니었다. semaphore로 동기하고 process간 데이터 전달은 메모리 공유로 한다.

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <semaphore.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #define	SEM_NAME	"mysem"
    #define FILE_MODE 0666
    struct shared{
    	sem_t mutex;
    	int count;
    } shared;
    
    int
    main(int argc, char **argv)
    {
    	int		fd, i, nloop, zero = 0;
    	//int		*ptr;
    	//sem_t	*mutex;
    	struct shared *ptr;
    
    	if (argc != 3)
    		perror("usage: incr2 <pathname> <#loops>");
    	nloop = atoi(argv[2]);
    
    		/* 4open file, initialize to 0, map into memory */
    	fd = open(argv[1], O_RDWR | O_CREAT, FILE_MODE);
    	write(fd, &shared, sizeof(struct shared));
    	ptr = mmap(NULL, sizeof(struct shared), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    	close(fd);
    
    		/* 4create, initialize, and unlink semaphore */
    	//mutex = sem_open(SEM_NAME, O_CREAT | O_EXCL, FILE_MODE, 1);
    	sem_init(&ptr->mutex,1,1);
    
    
    	sem_unlink(SEM_NAME);
    
    	setbuf(stdout, NULL);	/* stdout is unbuffered */
    	if (fork() == 0) {		/* child */
    		for (i = 0; i < nloop; i++) {
    			sem_wait(&ptr->mutex);
    			printf("child: %d\n", (ptr->count)++);
    			sem_post(&ptr->mutex);
    		}
    		exit(0);
    	}
    
    		/* 4parent */
    	for (i = 0; i < nloop; i++) {
    		sem_wait(&ptr->mutex);
    		printf("parent: %d\n", ptr->count++);
    		sem_post(&ptr->mutex);
    	}
    	exit(0);
    }
    
    pi@raspberrypi:~/Project/cCode/IPC $ ./a.out tt 100
    parent: 0
    parent: 1
    parent: 2
    parent: 3
    parent: 4
    parent: 5
    child: 6
    child: 7
    child: 8
    child: 9
    child: 10
    child: 11
    child: 12
    child: 13
    child: 14
    child: 15
    child: 16
    child: 17
    child: 18
    child: 19
    child: 20
    child: 21
    child: 22
    child: 23
    child: 24
    child: 25
    child: 26
    child: 27
    child: 28
    child: 29
    child: 30
    child: 31
    child: 32
    child: 33
    child: 34
    child: 35
    child: 36
    child: 37
    child: 38
    child: 39
    child: 40
    child: 41
    child: 42
    child: 43
    child: 44
    child: 45
    child: 46
    child: 47
    child: 48
    child: 49
    child: 50
    child: 51
    child: 52
    child: 53
    child: 54
    child: 55
    child: 56
    child: 57
    child: 58
    child: 59
    child: 60
    child: 61
    child: 62
    child: 63
    child: 64
    child: 65
    child: 66
    child: 67
    child: 68
    child: 69
    child: 70
    child: 71
    child: 72
    child: 73
    child: 74
    child: 75
    child: 76
    child: 77
    child: 78
    child: 79
    child: 80
    child: 81
    child: 82
    child: 83
    child: 84
    child: 85
    child: 86
    child: 87
    child: 88
    child: 89
    child: 90
    child: 91
    child: 92
    child: 93
    child: 94
    child: 95
    child: 96
    child: 97
    child: 98
    child: 99
    child: 100
    child: 101
    child: 102
    child: 103
    child: 104
    child: 105
    parent: 106
    parent: 107
    parent: 108
    parent: 109
    parent: 110
    parent: 111
    parent: 112
    parent: 113
    parent: 114
    parent: 115
    parent: 116
    parent: 117
    parent: 118
    parent: 119
    parent: 120
    parent: 121
    parent: 122
    parent: 123
    parent: 124
    parent: 125
    parent: 126
    parent: 127
    parent: 128
    parent: 129
    parent: 130
    parent: 131
    parent: 132
    parent: 133
    parent: 134
    parent: 135
    parent: 136
    parent: 137
    parent: 138
    parent: 139
    parent: 140
    parent: 141
    parent: 142
    parent: 143
    parent: 144
    parent: 145
    parent: 146
    parent: 147
    parent: 148
    parent: 149
    parent: 150
    parent: 151
    parent: 152
    parent: 153
    parent: 154
    parent: 155
    parent: 156
    parent: 157
    parent: 158
    parent: 159
    parent: 160
    parent: 161
    parent: 162
    parent: 163
    parent: 164
    parent: 165
    parent: 166
    parent: 167
    parent: 168
    parent: 169
    parent: 170
    parent: 171
    parent: 172
    parent: 173
    parent: 174
    parent: 175
    parent: 176
    parent: 177
    parent: 178
    parent: 179
    parent: 180
    parent: 181
    parent: 182
    parent: 183
    parent: 184
    parent: 185
    parent: 186
    parent: 187
    parent: 188
    parent: 189
    parent: 190
    parent: 191
    parent: 192
    parent: 193
    parent: 194
    parent: 195
    parent: 196
    parent: 197
    parent: 198
    parent: 199
    
    
    pi@raspberrypi:~/Project/cCode/IPC $ od -A d -t d tt
    0000000           2         128           0           0
    0000016         200
    000002
  • 다른 process간 named semaphore 사용(실패)

    세마포어로 데이터를 전달할 줄 알았으나, 동기화만 한다. 프로세스간 데이터를 공유할 방법이 없다. 다음 예제 shared memory로 공유한다. named semaphore는 잘 동작하는 듯 한데, 검증을 못했다.

    pi@raspberrypi:~/Project/cCode/IPC $ cat named_semaphore_prod.c 
    /* include main */
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <semaphore.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <signal.h>
    #define	NBUFF	 10
    #define	SEM_MUTEX	"mutex"	 	/* these are args to px_ipc_name() */
    #define	SEM_NEMPTY	"empty"
    #define	SEM_NSTORED	"nstored"
    #define SEM_PROGEND "end"
    
    int		nitems;					/* read-only by producer and consumer */
    struct {	/* data shared by producer and consumer */
      int	buff[NBUFF];
      sem_t	*mutex, *nempty, *nstored, *endprog;
    } shared;
    
    
    static void signal_hanlder (int signo)
    {
    /*
    * Technically, you shouldn't use printf() in a
    * signal handler, but it isn't the end of the
    * world. I'll discuss why in the section
    * "Reentrancy."
    */
      if(signo == SIGINT){
        printf ("Caught SIGINT!\ndelete named semaphore\n");
    	sem_unlink(SEM_MUTEX);
    	sem_unlink(SEM_NEMPTY);
    	sem_unlink(SEM_NSTORED);
    	sem_unlink(SEM_PROGEND);
        exit (EXIT_SUCCESS);
      }
    }
    
    int
    main(int argc, char **argv)
    {
    	int		i, items;
    	errno=0;
    
    //if (argc != 2)
    //		perror("usage: prodcons1 <#items>");
    //	nitems = atoi(argv[1]);
    		/* 4create three semaphores */
    
    	//무한 루프에서 세마포어 동작..
    	//signal handler로 삭제필요.
    
    	if(signal(SIGINT, signal_hanlder) == SIG_ERR){
    		fprintf(stderr, "cannot handle SIGINT\n");
    		exit(EXIT_FAILURE);
    	}
    
    
    	shared.mutex = sem_open(SEM_MUTEX, O_CREAT | O_EXCL, 0660, 1);
    	if(shared.mutex == SEM_FAILED && errno == EEXIST ){
    		printf("delete existing semaphore mutex\n");
    		sem_unlink(SEM_MUTEX);
    		shared.mutex = sem_open(SEM_MUTEX, O_CREAT | O_EXCL, 0660, 1);
    	} //if
    
    	shared.nempty = sem_open(SEM_NEMPTY, O_CREAT | O_EXCL, 0660, NBUFF);
    	if(shared.nempty== SEM_FAILED && errno == EEXIST ){
    		printf("delete existing semaphore nempty\n");
    		sem_unlink(SEM_NEMPTY);
    		shared.nempty = sem_open(SEM_NEMPTY, O_CREAT | O_EXCL, 0660, NBUFF);
    	} //if
    
    	shared.nstored = sem_open(SEM_NSTORED, O_CREAT | O_EXCL, 0660, 0);
    	if(shared.nstored== SEM_FAILED && errno == EEXIST ){
    		printf("delete existing semaphore nstored\n");
    		sem_unlink(SEM_NSTORED);
    		shared.nstored = sem_open(SEM_NSTORED, O_CREAT | O_EXCL, 0660, 0);
    
    	} //if
    
    	shared.endprog = sem_open(SEM_PROGEND, O_RDONLY);
    	if(shared.endprog== SEM_FAILED && errno == EEXIST ){
    		printf("delete existing semaphore endprog\n");
    		sem_unlink(SEM_PROGEND);
    		shared.endprog = sem_open(SEM_PROGEND, O_RDONLY);
    
    	} //if
    	//sem_getvalue(shared.endprog, &items);
    	//printf("producer. items are %d.\n",items);
    
    
    	while(1){
    
    		sem_wait(shared.nempty);	/* wait for at least 1 empty slot */
    		sem_wait(shared.mutex);
    		shared.buff[i % NBUFF] = i;	/* store i into circular buffer */
    		items--;
    		sem_post(shared.mutex);
    		sem_post(shared.nstored);	/* 1 more stored item */
    
    
    		//프로그램 end 확인.
    		//consum에서 nitems를 받지 말고,
    		//동기화 잘 된다는 생각으로
    		//prod, consum 양쪽 카운터..
    		//목표 카운터 도달하면 모두 종료.
    		//if(items<=0) break;
    		
    	}
    
    	sem_unlink(SEM_MUTEX);
    	sem_unlink(SEM_NEMPTY);
    	sem_unlink(SEM_NSTORED);
    	sem_unlink(SEM_PROGEND);
    
    
    	return 0;
    }
    pi@raspberrypi:~/Project/cCode/IPC $ cat named_semaphore_consu.c
    /* include main */
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <semaphore.h>
    #include <sys/stat.h>
    #include <errno.h>
    
    #define	NBUFF	 10
    #define	SEM_MUTEX	"mutex"	 	/* these are args to px_ipc_name() */
    #define	SEM_NEMPTY	"empty"
    #define	SEM_NSTORED	"nstored"
    #define SEM_PROGEND "end"
    
    int		nitems;					/* read-only by producer and consumer */
    struct {	/* data shared by producer and consumer */
      int	buff[NBUFF];
      sem_t	*mutex, *nempty, *nstored, *endprog;
    
    } shared;
    
    int
    main(int argc, char **argv)
    {
    	int		i;
    
    	if (argc != 2)
    		perror("usage: prodcons1 <#items>");
    	nitems = atoi(argv[1]);
    		/* 4create three semaphores */
    	shared.mutex = sem_open(SEM_MUTEX, O_RDWR);
    	shared.nempty = sem_open(SEM_NEMPTY, O_RDWR);
    	shared.nstored = sem_open(SEM_NSTORED, O_RDWR);
    	shared.endprog = sem_open(SEM_PROGEND, O_CREAT | O_EXCL, 0660, nitems);
    	if(shared.endprog == SEM_FAILED && errno == EEXIST ){
    		printf("delete existing semaphore endprog\n");
    		sem_unlink(SEM_PROGEND);
    		shared.endprog = sem_open(SEM_PROGEND, O_CREAT | O_EXCL, 0660, nitems);
    
    	} //if
    
    	for (i = 0; i < nitems; i++) {
    
    		sem_wait(shared.nstored);		/* wait for at least 1 stored item */
    		sem_wait(shared.mutex);
    
    		if (shared.buff[i % NBUFF] = i)
    			printf("buff[%d] = %d\n", i, shared.buff[i % NBUFF]);
    		sem_post(shared.mutex);
    		sem_post(shared.nempty);		/* 1 more empty slot */
    		
    	}
    	return 0;
    }
    https://stackoverflow.com/questions/32205396/share-posix-semaphore-among-multiple-processes