linux에서 mutex를 재귀적으로 사용하는 방법
아.. 모르고 썼으면 큰일날뻔 했군요.
pthread 프로그래머가 Win32에서 밟기 쉬운 지뢰 하나
미리 밝혀두지만 rein이 정말 본격적으로 Windows 시스템 프로그래밍을 한 것은 작년 부터다. 그런 의미에서 겪었던 삽질 하나를 밝혀둔다.[1]
Linux system에서 널리 사용되는 posix thread (이하 pthread) 라이브러리의 가장 기본적인 동기화 메커니즘은 pthread_mutex_t 라는 타입으로 불리는 일종의 mutex다.[2]이걸 쓰던 사람이 Windows의 CRITICAL_SECTION 이나 Win32 mutex를 사용할 때 가장 실수하기 쉬운 것.
Win32의 CRITICAL_SECTION이나 mutex는 recursive하게[3]lock을 잡는 것을 허용한다[4]
거꾸로 Win32 프로그래머가 linux pthread를 쓴다면 주의할 것,
pthread의 mutex는기본적으로recursive–locking을 허용하지 않는다
즉, 다음과 같은 코드는 영원히 정지한다[...]
pthread_mutex_lock( &lock );
pthread_mutex_lock( &lock ); // 이 줄을 벗어날 수 없다pthread_mutex_unlock( &lock );
pthread_mutex_unlock( &lock );
Win32에 익숙한 프로그래머라면 내가 주석처리한 저 코드를 보고 갸웃할지도 모른다. 그렇지만 pthread_mutex의기본동작은 recursive–locking에 대한 거부다. 그렇지만 다음과 같은 방식으로 mutex를 생성하면 recursive–locking을 허용하게 만들 수 있다.
pthread_mutexattr_t attr;
pthread_mutexattr_init( &attr );
int val = PTHREAD_MUTEX_RECURSIVE_NP;
pthread_mutexattr_settype( &attr, val);
pthread_mutex_init( &lock, &attr );
이런 조금 귀찮은 과정을 거치면 recursive–locking을 지원하는 — win32 프로그래머가 좀 더 익숙해 할, 혹은 그런 종류의 lock이 필요한 상황에서 써야하는 — pthread용 mutex가 생성된다.
근본(…)이 *nix 세계의 사람인 rein은[5]pthread의 기본 동작을 조금 더 좋아한다. 이유는 예전에 설명했던Dead-lock;데드락을 막는 locking protocol((Lock들에 번호를 부여하고, 특정 순서로만 lock잡는걸 허용하는 것))때문이다.Win32의 기본적인 recursive–locking에서는 다음 시나리오에서 필패한다(잠재적인 dead–lock을 허용한다)
- lock L2
- … some code block …
- lock L1
- lock L2
- lock L3
- …
이 경우에 pthread_mutex라면 4에서 이미 프로그램이 멈추기 때문에(기본적인 pthread_mutex 동작에서), 상대적으로 빨리 눈치채고 대응할 수 있다. (아마도 프로그램이 릴리즈 되기 전에). 반면에 Win32환경에서는 운만 좋으면[6]—운이 나쁘다고 봐도 된다— 릴리즈되기 전에 데드락이 숨어있다는 것을 알 수 없게 된다.
물론win32도 좀 쓰기 시작한지라lock 전체의 잡는 순서를 로깅하는 간단한 per-thread 객체를 하나 써서 lock순서를 추적하기 때문에, 이런 일은 바로 눈치채고 있긴하지만, 가끔은 pthread_mutex가 그리워지기도 해서 이런 글을 끄적대 본다.
ps. 덤으로 intel TBB의 hash_table의숨겨져있는 lock들은pthread의 convention을 따른다. 즉 두 번 잡으려고하면 해당 스레드는 거의 영원히 멈추게 된다. 그런 의미에서 주의해야.
- 덤으로 금요일 저녁에 Rica한테 잘못된 사실을 하나 말했던 것을 정정하려한다 [↩]
- 물론 spin–lock도 pthread_spinlock_t로 제공된다 [↩]
- 재귀적으로. 즉 thread A가 어떤 mutex나 CS의 락을 얻은 상태에서 또 해당 락을 얻으려고 시도하면 잡을 수 있다 [↩]
- 내가 Rica한테 잘못 설명한 부분이 여기. 난 Mutex는 재귀적으로 못잡는다고 생각했다. 근데 되더라고… [↩]
- 시스템 프로그래밍을 Solaris 2.x에서 시작해서 Redhat과 Fedora를 거쳐 지금에 이르렀다 [↩]
- 3이 실행되기전에 L1을 잡는 스레드가 없기만 하면된다 [↩]
'프로그래밍???' 카테고리의 다른 글
PERL로 파일입출력 (0) | 2012.04.06 |
---|---|
Perl로 시간 처리하기 (0) | 2012.04.06 |
clock_gettime에 대한 자료 (0) | 2011.08.04 |
FIFO 사용에 대한 오류 및 문제 (0) | 2011.08.02 |
mkdir -p 옵션 구현 (0) | 2011.06.17 |
linux에서 한글 깨짐 현상
[Linux] 한글 깨짐 현상(인코딩 설정)
일반적으로 리눅스 콘솔(X-windows를 사용하지 않을 경우)에서는 한글이 깨져 나온다.
또한 SSH 클라이언트를 통해 접속하는 경우에도 마찬가지로 한글이 깨진다.
이럴 경우에 아래와 같이 수행하여 해결한다.
1. 현재 설정된 인코딩 설정 확인
[root@localhost etc]$ echo $LANG
ko_KR.UTF-8
2. 인코딩 설정 해제
[root@localhost sysconfig]# unset LANG
[root@localhost sysconfig]# LANG=C
3. 사용 가능한 인코딩 설정 확인
[root@localhost etc]$ locale -a | grep ko
ko_KR
ko_KR.euckr
ko_KR.utf8
korean
korean.euc
ru_RU.koi8r
ru_UA.koi8u
tg_TJ.koi8t
uk_UA.koi8u
4. /etc/sysconfig/i18n 파일 수정
[root@localhost sysconfig]# vi i18n
#LANG="ko_KR.UTF-8"
LANG="ko_KR.euckr"
'프로그래밍??? > 리눅스 및 서버 기타' 카테고리의 다른 글
centos5에서 root 암호를 잊어버렸을 경우... (0) | 2012.04.19 |
---|---|
리눅스 shell script로 날짜별로 로그파일 지우기 (0) | 2012.04.04 |
사용자 추가 (0) | 2012.03.24 |
[vsftp]500 OOPS:could not bind listening IPv4 socket ?? (0) | 2012.02.10 |
SSH ROOT 계정/IP 로그인 차단하기 (0) | 2011.12.02 |
사용자 추가
출처 : 수퍼유저코리아(www.superuser.co.kr)
-- 필요시에는 위의 링크에서 자료를 찾길 바랍니다. --
useradd / adduser
새로운 사용자를 생성할때 사용하는 명령어이다.
계정사용자를 생성할 수도 있고, 메일사용자를 생성할 수도 있다.
용도에 맞는 원하는 계정을 생성할때 사용하는 명령어이다.
또한 이 명령어는 "useradd -D"명령어와 반드시 함께 알아두기 바란다. (강추)
계정을 생성하는 관리자용 명령어이므로 일반사용자들은 사용하지 않는 명령어이다.
또한 리눅스에서 useradd와 adduser명령어가 어떻게 다르냐고 질문하시는 분들이 있다.
다음의 사실을 명확하게 확인하기 바란다.
[root@host3 root]#ls -l /usr/sbin/adduser
lrwxrwxrwx 1 root root 7 8월 28 02:29 /usr/sbin/adduser -> useradd
[root@host3 root]#
즉, adduser명령어는 useradd명령어로 링크되어 있는 것에 불과하다.
따라서 실제로 adduser명령어와 useradd명령어는 완전히 동일하다고 보면 된다.
앞으로 이런 문제로 고민하는 일이 없기를 바라면서...
서버관리자가 해야하는 계정생성 관련업무에는 다음과 같은 것들이 있다.
- /etc/passwd 파일에 사용자의 계정(ID 및 패스워드)생성 - /etc/shadow 파일에 계정 패스워드 등록 - /etc/group파일에 사용자의 그룹생성 - /home에 사용자의 홈디렉토리 생성 - FTP사용을 위한 FTP사용 환경설정 - 메일사용을 위한 메일환경설정 - 사용자의 로그인정보 및 환경설정 - 사용자의 디렉토리 및 파일 소유권 변경 및 확인 - DB 사용을 위한 환경설정 및 응용프로그램사용을 위한 환경설정 - 기타 응용 소프트웨어 사용을 위한 설정등 |
이외에도 여러가지 작업들이 있지만, 서버관리자는 새로운 계정사용자가 생성이 되면 기본적으로 위와
같은 작업을 해야한다.
이런 업무중에 계정생성에 관련된 작업을 useradd를 이용하여 작업한다.
사용형식
useradd [-c comment] [-d home_dir]
[-e expire_date] [-f inactive_time]
[-g initial_group] [-G group[,...]]
[-m [-k skeleton_dir] | -M] [-p passwd]
[-s shell] [-u uid [ -o]] [-n] [-r] login
사용예 #1
useradd로 간단히 계정을 생성하는 예를 보았으므로 이번에는 좀 더 다양한 옵션사용의 예를 보도록 하자.
sspark1이라는 계정사용자를 다음과 같이 새로 생성하였다.
[root@host3 root]#useradd -d /home/sspark1 -u 600 -s /bin/csh sspark1
[root@host3 root]#
즉, 홈디렉토리위치를 /home/sspark1로 지정하였고, UID를 600으로 지정하였으며, 기본사용쉘을 C Shell로 지정하였다.
다음은 결과를 확인하 것이다.
[root@host3 root]#grep sspark1 /etc/passwd
sspark1:x:600:600::/home/sspark1:/bin/csh
[root@host3 root]#
[root@host3 root]#grep sspark1 /etc/group
sspark1:x:600:
[root@host3 root]#
[root@host3 root]#ls -al /home/sspark1
합계 32
drwx------ 3 sspark1 sspark1 4096 9월 19 11:46 .
drwxr-xr-x 8 root root 4096 9월 19 11:46 ..
-rw-r--r-- 1 sspark1 sspark1 24 9월 19 11:46 .bash_logout
-rw-r--r-- 1 sspark1 sspark1 191 9월 19 11:46 .bash_profile
-rw-r--r-- 1 sspark1 sspark1 124 9월 19 11:46 .bashrc
-rw-r--r-- 1 sspark1 sspark1 854 9월 19 11:46 .emacs
-rw-r--r-- 1 sspark1 sspark1 120 9월 19 11:46 .gtkrc
drwxr-xr-x 3 sspark1 sspark1 4096 9월 19 11:46 .kde
[root@host3 root]#
이렇게 옵션을 직접 지정하면 기본설정값에 우선하여 생성이 됨을 알아두기 바란다.
사용예 #2
다음의 예는 좀 더 다양한 옵션을 사용하여 계정을 생성한 예이다.
[root@host3 root]#useradd -c 박성수 -e 2004-12-12 -d /home/sspark2 -u 601 -s /bin/ksh -p 12345 sspark2
[root@host3 root]#
위에서 사용한 옵션을 간단히 설명하면 다음과 같다.
. -c 박성수 : 계정사용자의 간단한 설명
. -e 2004-12-12 : 계정사용 종료일자
. -d /home/sspark2 : 홈디렉토리 위치
. -u 601 : UID 601로 지정
. -s /bin/ksh : 사용할 기본쉘을 Korn Shell로 지정
. -p 12345 : 패스워드를 12345로 지정
. sspark2 : 생성할 계정명
위와 같이 지정한 다음 생성된 내용을 간단히 확인한 것이다.
[root@host3 root]#grep sspark2 /etc/passwd
sspark2:x:601:601:박성수:/home/sspark2:/bin/ksh
[root@host3 root]#
[root@host3 root]#grep sspark2 /etc/shadow
sspark2:12345:12314:0:99999:7::12764:
[root@host3 root]#
[root@host3 root]#grep sspark2 /etc/group
sspark2:x:601:
[root@host3 root]#
이상과 같이 다양한 옵션을 사용하여 useradd를 사용할 수 있음을 알 수 있을 것이다.
위에서도 말씀드렸지만 useradd명령과 함께 "useradd -D"명령도 추가적으로 알아두기 바란다.
'프로그래밍??? > 리눅스 및 서버 기타' 카테고리의 다른 글
리눅스 shell script로 날짜별로 로그파일 지우기 (0) | 2012.04.04 |
---|---|
linux에서 한글 깨짐 현상 (0) | 2012.03.26 |
[vsftp]500 OOPS:could not bind listening IPv4 socket ?? (0) | 2012.02.10 |
SSH ROOT 계정/IP 로그인 차단하기 (0) | 2011.12.02 |
서버 관리 기본 명령 1 (0) | 2011.08.02 |
프로시저 내에서 트리거 생성 쿼리
'프로그래밍??? > 오라클' 카테고리의 다른 글
SQL%ROWCOUNT 편리함 ^^ (0) | 2012.04.04 |
---|---|
PLSQL문법 정리 (730) | 2012.04.04 |
SQLPLUS에서 외부 스크립트 실행하기 (0) | 2012.04.04 |
oracle client를 통한 접속 (0) | 2011.12.07 |
instant client 설치하기 (0) | 2011.12.07 |