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

memory based semaphore, unix network programming p241

이름있는 세마포어 말고 메모리에 올려 사용하는 방법도 있다. 책은 sem_init(…, 두번째 arg,…)에서 두번째 입력하는 숫자를 thread에서 공유할 거면 0, 프로세스간 할거면 1로 하라고 한다. 1로 하여 thread도 잘 된다.

named semaphore는 포인터를 선언했고 파일에 영역을 만들었다. 이와 다르게 직접 데이터를 선언하고 주소로 넘겨줘야 한다.

ipcs로 보일 법 한데, 안 보인다. 무엇이 잘못되었는지 모르겠다.

/* include main */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <unistd.h>
#define	NBUFF	 10
#define	SEM_MUTEX	"mutex"	 	/* these are args to px_ipc_name() */
#define	SEM_NEMPTY	"empty"
#define	SEM_NSTORED	"nstored"

int		nitems;					/* read-only by producer and consumer */
struct {	/* data shared by producer and consumer */
  int	buff[NBUFF];
  //포인터 대신 세마포어로 변경.
  //sem_t	*mutex, *nempty, *nstored;
  sem_t	mutex, nempty, nstored;		/* semaphores, not pointers */

} shared;

void	*produce(void *), *consume(void *);

int
main(int argc, char **argv)
{
	pthread_t	tid_produce, tid_consume;

	if (argc != 2)
		perror("usage: prodcons1 <#items>");
	nitems = atoi(argv[1]);
		/* 4create three semaphores */
	//memory based로 변경.
	/*
	shared.mutex = sem_open(SEM_MUTEX, O_CREAT | O_EXCL,
							0660, 1);
	shared.nempty = sem_open(SEM_NEMPTY, O_CREAT | O_EXCL,
							 0660, NBUFF);
	shared.nstored = sem_open(SEM_NSTORED, O_CREAT | O_EXCL,
							  0660, 0);
							  */


	//두번째 파라미터를 0으로 설정해야 thread간 전달.
	//sem_init(&shared.mutex, 1, 1) 설정해도 잘 됨..

	sem_init(&shared.mutex, 0, 1);
	sem_init(&shared.nempty, 0, NBUFF);
	sem_init(&shared.nstored, 0, 0);


		/* 4create one producer thread and one consumer thread */
	//pthread_setconcurrency(2);
	//pthread_setconcurrency();
	pthread_create(&tid_produce, NULL, produce, NULL);
	pthread_create(&tid_consume, NULL, consume, NULL);

		/* 4wait for the two threads */
	pthread_join(tid_produce, NULL);
	pthread_join(tid_consume, NULL);

		/* 4remove the semaphores */
	//메모리 베이스로 변경.
	/*
	sem_unlink(SEM_MUTEX);
	sem_unlink(SEM_NEMPTY);
	sem_unlink(SEM_NSTORED);
	*/


	//ipcs로 확인하기위해 대기
	sleep(10);

	sem_destroy(&shared.mutex);
	sem_destroy(&shared.nempty);
	sem_destroy(&shared.nstored);

	exit(0);
}
/* end main */

/* include prodcons */
void *
produce(void *arg)
{
	int		i;

	for (i = 0; i < nitems; i++) {

		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 */
		sem_post(&shared.mutex);
		sem_post(&shared.nstored);	/* 1 more stored item */


	}
	return(NULL);
}

void *
consume(void *arg)
{
	int		i;
	int tmpnempty, tmpmutex, tmpnstored;

	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(NULL);
}
/* end prodcons */
pi@raspberrypi:~/Project/cCode/IPC $ ipcs

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      

------ Semaphore Arrays --------
key        semid      owner      perms      nsems     

ipcs는 system V 기능이라 posix semaphore는 해당하지 않는다. 보이지 않음이 당연하다.

unix network programming, vol 2

isbn:  9780130810816

대학교 vol 1을 읽었고 너무 오래된 시스템이라 잘 실행안됬음을 기억했다. 가벼운 마음으로 IPC를 알아보려 찾았는데, 600페이지 책 한 권을 읽고 있다. 책도 나온지 너무 오래되어 웬만하면 하나 사려고 했는데, 종이책으로만 있다!! 인터넷에서 잘 찾았다.

아래 그림은 개요장에 있는데 이 그림으로 길고 지루한 길을 쉽게 갈 수 있다. 예상한 바와 같이 파일로 정보를 공유함은 너무 급이 떨어진다. 고급지게 메세지 큐, 파이프, 세마포어로 가자고!!

이런 책을 찾지 않고, 스스로 고민하고 있으면 낮은 성과를 많은 시간을 들여 얻는다. 내가 생각했었고 더 깊은 내용까지 설명한다. 내가 무엇을 모르는지 알고, 어디 있는지 찾는 능력이 중요하다.

근데 너무 길다. System V는 먼지 모르겠으나 오래되어 포기했고 POSIX만 찾아 보는데도 쉽게 못나간다. 너무 깊게 들어가는 기분이다.

https://www.joinc.co.kr/w/Site/system_programing/Book_LSP/ch08_IPC