콘텐츠로 바로가기

now0930 일지

이런저런 생각

  • 홈
  • 비공개
  • 강좌
  • 잔여 작업 조회
  • 위치

semaphore p223 ~ p238

name semaphore는 /dev/shm에 저장된다. 이름을 엄한 /tmp/xxx 이런 식으로 만들면 세마포어를 만들 수 없다. segment error로 죽는다. 책에서는 /tmp/로 넣어도 잘 동작해서 확인하는데 오래 걸렸다.

디버그 하다 중간에 멈추면 /dev/shm에 sem*로 파일을 지울 수 없어 다음 실행에 세마포어를 받을 수 없다. 처음 시작 전 자기 이름으로 된 세마포어 있으면 지워야 한다.

thread를 돌리면 미친 race condition이 피곤하게 한다. 참 헷갈리는데, 자주보면 익숙해 지겠지. thread를 돌리면 순서는 이제 별 의미 없는 듯 하다. sem_post하는 즉시 자기 thread를 실행하는게 아니라 다른 thread로 가서 프로그램을 실행한다. wait로 thread 이후 행을 잘 막는 게 핵심인 듯 하다.

/* include main */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <semaphore.h>
#include <sys/stat.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;
} shared;

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

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

	if (argc != 2)
		perror("usage: prodcons1 <#items>");
	nitems = atoi(argv[1]);
		/* 4create three semaphores */
	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);

		/* 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);
	exit(0);
}
/* end main */

/* include prodcons */
void *
produce(void *arg)
{
	int		i;
	int tmpnempty, tmpmutex, tmpnstored;

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


		//value check
		//sem_getvalue(shared.nempty, &tmpnempty);
		//sem_getvalue(shared.nstored, &tmpnstored);
		//sem_getvalue(shared.mutex, &tmpmutex);

		sem_wait(shared.nempty);	/* wait for at least 1 empty slot */
		sem_wait(shared.mutex);

		//value check
		//sem_getvalue(shared.nempty, &tmpnempty);
		//sem_getvalue(shared.nstored, &tmpnstored);
		//sem_getvalue(shared.mutex, &tmpmutex);



		shared.buff[i % NBUFF] = i;	/* store i into circular buffer */
		sem_post(shared.mutex);
		sem_post(shared.nstored);	/* 1 more stored item */
		//value check
		//sem_getvalue(shared.nempty, &tmpnempty);
		//sem_getvalue(shared.nstored, &tmpnstored);
		//sem_getvalue(shared.mutex, &tmpmutex);


	}
	return(NULL);
}

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

	for (i = 0; i < nitems; i++) {
		//value check
		//sem_getvalue(shared.nempty, &tmpnempty);
		//sem_getvalue(shared.mutex, &tmpmutex);
		//sem_getvalue(shared.nstored, &tmpnstored);


		sem_wait(shared.nstored);		/* wait for at least 1 stored item */
		sem_wait(shared.mutex);
		//value check
		//sem_getvalue(shared.nempty, &tmpnempty);
		//sem_getvalue(shared.mutex, &tmpmutex);
		//sem_getvalue(shared.nstored, &tmpnstored);


		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 */
		//value check
		//sem_getvalue(shared.nempty, &tmpnempty);
		//sem_getvalue(shared.mutex, &tmpmutex);
		//sem_getvalue(shared.nstored, &tmpnstored);


	}
	return(NULL);
}
/* end prodcons */
pi@raspberrypi:~/Project/cCode/IPC $ gdb --args ./a.out  3
GNU gdb (Raspbian 8.2.1-2) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
...

(gdb) info b
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x000107b4 in produce at semaphore.c:72
	breakpoint already hit 3 times
2       breakpoint     keep y   0x00010884 in consume at semaphore.c:108
	breakpoint already hit 3 times
(gdb) r
Starting program: /home/pi/Project/cCode/IPC/a.out 3
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[New Thread 0xb6e31460 (LWP 2842)]
[New Thread 0xb6630460 (LWP 2843)]
[Switching to Thread 0xb6e31460 (LWP 2842)]

Thread 2 "a.out" hit Breakpoint 1, produce (arg=0x0) at semaphore.c:72
72			sem_wait(shared.nempty);	/* wait for at least 1 empty slot */
1: shared = {buff = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, mutex = 0xb6ff8000, 
  nempty = 0xb6ff7000, nstored = 0xb6ff6000}
2: *shared.nempty = {
  __size = "\024\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 20}
3: *shared.nstored = {
  __size = "\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 0}
4: *shared.mutex = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
(gdb) c
Continuing.
[Switching to Thread 0xb6630460 (LWP 2843)]

Thread 3 "a.out" hit Breakpoint 2, consume (arg=0x0) at semaphore.c:108
108			sem_wait(shared.nstored);		/* wait for at least 1 stored item */
1: shared = {buff = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, mutex = 0xb6ff8000, 
  nempty = 0xb6ff7000, nstored = 0xb6ff6000}
2: *shared.nempty = {
  __size = "\024\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 20}
3: *shared.nstored = {
  __size = "\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 0}
4: *shared.mutex = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
(gdb) c
Continuing.
[Switching to Thread 0xb6e31460 (LWP 2842)]

Thread 2 "a.out" hit Breakpoint 1, produce (arg=0x0) at semaphore.c:72
72			sem_wait(shared.nempty);	/* wait for at least 1 empty slot */
1: shared = {buff = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, mutex = 0xb6ff8000, 
  nempty = 0xb6ff7000, nstored = 0xb6ff6000}
2: *shared.nempty = {
  __size = "\022\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 18}
3: *shared.nstored = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
4: *shared.mutex = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
(gdb) c
Continuing.
[Switching to Thread 0xb6630460 (LWP 2843)]

Thread 3 "a.out" hit Breakpoint 2, consume (arg=0x0) at semaphore.c:108
108			sem_wait(shared.nstored);		/* wait for at least 1 stored item */
1: shared = {buff = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, mutex = 0xb6ff8000, 
  nempty = 0xb6ff7000, nstored = 0xb6ff6000}
2: *shared.nempty = {
  __size = "\022\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 18}
3: *shared.nstored = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
4: *shared.mutex = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
(gdb) c
Continuing.
[Switching to Thread 0xb6e31460 (LWP 2842)]

Thread 2 "a.out" hit Breakpoint 1, produce (arg=0x0) at semaphore.c:72
72			sem_wait(shared.nempty);	/* wait for at least 1 empty slot */
1: shared = {buff = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, mutex = 0xb6ff8000, 
  nempty = 0xb6ff7000, nstored = 0xb6ff6000}
2: *shared.nempty = {
  __size = "\022\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 18}
3: *shared.nstored = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
4: *shared.mutex = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
(gdb) c
Continuing.
buff[1] = 1
[Thread 0xb6e31460 (LWP 2842) exited]
[Switching to Thread 0xb6630460 (LWP 2843)]

Thread 3 "a.out" hit Breakpoint 2, consume (arg=0x0) at semaphore.c:108
108			sem_wait(shared.nstored);		/* wait for at least 1 stored item */
1: shared = {buff = {0, 1, 2, 0, 0, 0, 0, 0, 0, 0}, mutex = 0xb6ff8000, 
  nempty = 0xb6ff7000, nstored = 0xb6ff6000}
2: *shared.nempty = {
  __size = "\022\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 18}
3: *shared.nstored = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
4: *shared.mutex = {
  __size = "\002\000\000\000\200\000\000\000\000\000\000\000\000\000\000", 
  __align = 2}
(gdb) c
Continuing.
buff[2] = 2
[Thread 0xb6ffa070 (LWP 2841) exited]
[Inferior 1 (process 2841) exited normally]
(gdb) 
https://unix.stackexchange.com/questions/275650/where-is-a-named-semaphore-stored

이 글 공유하기:

  • Tweet
발행일 2020-07-17글쓴이 이대원
카테고리 생활코딩 태그 c, linux, network program, pthread, semaphore

댓글 남기기응답 취소

이 사이트는 Akismet을 사용하여 스팸을 줄입니다. 댓글 데이터가 어떻게 처리되는지 알아보세요.

글 내비게이션

이전 글

sync, mutex. unix network programming p161

다음 글

unix network programming, vol 2

2025 5월
일 월 화 수 목 금 토
 123
45678910
11121314151617
18192021222324
25262728293031
4월    

최신 글

  • common mode, differential mode 2025-05-11
  • signal conditioner, 신호 처리기 2025-05-10
  • strain gage 2025-05-09
  • 칼만 필터 2025-05-01
  • positioner(I/P) 2025-04-26

카테고리

  • 산업계측제어기술사
  • 삶 자국
    • 책과 영화
    • 투자
  • 생활코딩
    • LEGO
    • ROS
    • tensorflow
  • 전기기사
  • 피아노 악보

메타

  • 로그인
  • 엔트리 피드
  • 댓글 피드
  • WordPress.org

페이지

  • 소개
  • 잔여 작업 조회
    • 작업 추가
    • 작업의 사진 조회
    • 작업 수정 페이지
  • 사진
    • GPS 입력된 사진
    • 사진 조회
  • 위치
    • 하기 휴가 방문지
    • 해외 출장

태그

android bash c docker driver FSM gps java kernel LEGO linux mysql network program opcua open62541 plc programmers python raspberry reinforcementLearning ros state space system program tensorflow transfer function 경제 미국 민수 삼국지 세계사 실기 에너지 역사 유전자 일본 임베디드 리눅스 전기기사 조선 중국 채윤 코딩 테스트 통계 한국사 한국어

팔로우하세요

  • Facebook
now0930 일지
WordPress로 제작.