http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Thread/Beginning/Mutex


1 히스토리 

  1. 내용 대폭 수정 : 2010/2/19 

2 공유 자원에 대한 접근 제어 

다수의 객체가 공유 자원에 접근하려고 하면, (공유 자원의 종류에 따라서)접근 시점을 동기화 시켜줄 필요가 생긴다. 여기에서 동기화란 시간과 공간을 맞추어 준다는 의미로, 즉 공유 자원 영역 (공간)에 접근하는 객체들의 진입 시간을 제어할 수 있어야 함을 의미한다.

멀티 Thread(쓰레드) 프로그램 역시 공유 자원에 여러 개의 쓰레드가 접근할 수 있으므로 공유 자원 영역에 대한 동기화가 필요 하다.

카운팅 프로그램을 예를 들어 보자. 카운트 변수는 전역:::변수(:12)로 A,B 두개의 쓰레드가 공유하면서, 1씩 증가하는 카운팅 정보를 유지하기 위해 사용된다. 공유 자원 영역 즉 "count 값을 읽어 오고, 연산을 해서 저장하는" 영역에 대한 쓰레드간 동기화가 이루어지지 않는 다면 아래와 같은 일이 발생할 수 있을 것이다.
  1. global int count = 0
  2. A 쓰레드가 count값 0을 읽는다.
  3. B 쓰레드가 count값 0을 읽는다.
    • A 쓰레드가 카운팅 연산을 하기 전에 B쓰레드가 접근해 버린 상황이다.
  4. A 쓰레드가 count+1 연산을 하고 값을 쓴다. count = 1
  5. B 쓰레드가 count+1 연산을 하고 값을 쓴다. count = 1
A와 B쓰레드가 한번씩 카운팅 연산을 했으므로, count값은 2가 되어야 하겠지만, 실제로는 1이 저장되어 버렸다.

이러한 문제의 해결을 위해서 쓰레드를 동기화 시켜줄 필요가 있다.

3 동기화 달성의 방법 

일반적으로 동기화는 "공간과 시간"을 제어하는 방식으로 이루어진다. 즉 "접근 제어가 필요한 공간"을 지정하고 지정한 "공간에 진입 할 수 있는 시간"을 제어하는 방식이다.

여기에서 "접근 제어가 필요한 공간"에는 보호 해야 할 공유 자원이 놓인다. 보호 해야할 공유 자원이 있는 공간을 임계 영역이라고 한다. 시간 제어는 해당 임계 영역에 동 시간에 단지 하나의 쓰레드만 접근하도록 제한 하는 방식으로 이루어진다.

임계영역에 들어가기 위한 하나의 키를 가지고 경쟁하는 것으로 이해하면 된다. 임계영역에 들어가기 위한 키는 단지 하나 밖에 없으므로 어떤 스레드가 키를 얻어서 임계영역에 진입하면, 다른 스레드는 키를 얻을 때까지 - 앞서 임계영역에 진입한 프로세스가 키를 되돌려줄 때까지 - 기다려야 한다.

 
위의 카운팅 프로그램을 예로 설명해보자. 임계 영역은
  1. count 값을 읽어와서
  2. 카운팅 연산을 하고
  3. 연산 결과를 저장하는
코드 영역으로 지정할 수 있을 것이다.

이 임계 영역에는 오직 하나의 쓰레드만이 진입할 수 있다. 즉 쓰레드 A가 임계 영역에 진입해서 코드를 수행중에 있다면 쓰레드 B는 임계 영역 밖에서 기다려야 한다. 이렇게 쓰레드를 동기화 시킴으로써, 아래와 같이 제대로된 카운팅 연산을 보장할 수 있게 된다.
  1. global int count = 0;
  2. A 쓰레드가 임계 영역에 진입
  3. B 쓰레드도 임계 영역 진입을 시도하지만, A 쓰레드가 진입해 있으므로 임계 영역 밖에서 대기한다.
  4. A 쓰레드가 count 값을 읽고
  5. 카운팅 연산을 해서
  6. 값을 저장한다. count = 1
  7. A 쓰레드가 임계 영역에서 빠져나온다.
  8. 비로서 B 쓰레드가 임계 영역에 진입해서
  9. count 값 1을 읽어서 카운팅 연산을 하고 저장한다. count = 2
제대로 카운팅 연산이 되는걸 확인할 수 있다.

4 Mutex 

뮤텍스는 pthread에서 제공하는 동기화 매커니즘으로 공유 자원 공간에 대한 접근 시간 제어로 동기화를 달성한다. 기본적인 매커니즘은 세마포어(:12)와 비슷하다. 특히 POSIX(:12) 세마포어와 비슷하며, 동기화 매커니즘으로 뮤텍스 대신 세마포어를 사용할 수도 있다. 동기화 매커니즘의 핵심은 상호 배제로 다음과 같이 달성 한다.

global int v = 1;
lock()
{
    while(1)
    {
        if (v==1)
            break;
    }
    v = 0;
    return 1;
}

unlock()
{
    v = 1;
    break;
}
어디까지나 매커니즘 상으로 그렇다는 얘기고, 세마포어와 마찬가지로 busy wait 상태에 놓이지 않음을 보장한다.

상호 배제는 잠금 형식으로 이루어진다. 쓰레드는 잠금 v를 얻어야 임계 영역에 진입할 수 있다. 임계 영역을 빠져나오면 잠금을 되돌려 줘서 다른 쓰레드가 잠금을 얻을 수 있도록 한다.

뮤텍스 메커니즘의 특징을 정리했다.

  • Atomicity - mutex 잠금(lock)는 최소단위 연적(atomic operation) 으로 작동한다. 이말의 뜻은 하나의 쓰레드가 mutex 를 이용해서 잠금을 시도하는 도중에 다른 쓰레드가 mutex 잠금을 할수없도록 해준다는 뜻이다. 한번에 하나의 mutex 잠금을 하도록 보증해준다.
  • Singularity - 만약 스레드가 mutex 잠금을 했다면, 잠금을 한 쓰레드(:12)가 mutex 잠금을 해제 하기 전까지 다른 어떠한 쓰레드도 mutex 잠금을 할수 없도록 보증해준다.
  • Non-Busy Wait - 바쁜대기 상태에 놓이지 않는다는 뜻으로, 하나의 쓰레드가 mutex 잠금을 시도하는데 이미 다른 쓰레드가 mutex 잠금을 사용하고 있다면 이쓰레드는 다른 쓰레드가 락을 해제하기전까지 해당 지점에 머물러 있으며 이동안은 어떠한 CPU 자원도 소비하지 않는다 (이를테면 sleep). 

5 뮤텍스 만들기 

뮤텍스를 생성하기 위해서 우리는 먼저, 뮤텍스정보를 저장하기 위한 타입인 pthread_mutex_t 를 선언해주고 이것을 초기화 해주어야 한다. 선언과 초기화의 가장간단한 방법은 PTHREAD_MUTEX_INITIALIZER 상수를 할당하는 것으로 아래와 같이 사용할수 있다.
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;

혹은 pthread_mutex_init(3)함수로 뮤텍스를 생성할 수도 있다.
#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutex_attr *attr);
  • mutex : 뮤텍스 객체
  • attr : 뮤텍스 생성 특성, NULL 이면 기본 특성을 가진다. 

6 뮤텍스 잠금, 잠금해제, 제거 

뮤텍스 잠금을 위한 함수로는 pthread_mutex_lock() 함수를 제공한다. 이 함수는 해당 뮤텍스에 대해서 잠금을 시도하는데, 만약 잠그려는 뮤텍스가 다른 쓰레드에 의해서 이미 잠겨있다면, 잠금을 얻을수 있을때까지 - 이미 잠근 다른 쓰레드가 뮤텍스의 잠금을 해제할때까지 - 봉쇄(블럭)되게 된다. 다음은 이러한 뮤텍스 잠금을 얻기 위한 지원함수들이다.
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_destory(pthread_mutex_t *mutex);

pthread_mutex_trylock() 를 사용하면 잠금을 얻을수 없을경우 해당 코드에서 블럭되지 않고 바로 에러코드를 돌려준다. 즉 pthread_mutex_lock 의 비봉쇄 버젼이라고 생각하면 된다.

뮤텍스 잠금을 얻은후 해당 영역에서의 작업을 마친후 잠금을 해제하기 위해서 사용한다. 사용되는 함수는 pthread_mutex_unlock(3) 이며 함수원형은 다음과 같다.
int pthread_mutex_unlock(pthread_mutex_t *mutex);
다음은 쓰레드간 공유되는 자원을 위해서 잠금을 어떻게 사용하는지를 보여주는 간단한 예제다.

예제: mutex_lock.c
#include <stdio.h>  
#include <unistd.h>  
#include <pthread.h>  
 
int ncount;    // 쓰레드간 공유되는 자원 
pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER; // 쓰레드 초기화 
 
void* do_loop(void *data) 
{ 
    int i; 
    for (i = 0; i < 10; i++) 
    { 
        pthread_mutex_lock(&mutex); // 잠금을 생성한다. 
        printf("loop1 : %d\n", ncount); 
        ncount ++; 
        if(i == 10) return;
        pthread_mutex_unlock(&mutex); // 잠금을 해제한다. 
        sleep(1); 
    } 
} 
 
void* do_loop2(void *data) 
{ 
    int i; 
 
    // 잠금을 얻으려고 하지만 do_loop 에서 이미 잠금을  
    // 얻었음으로 잠금이 해제될때까지 기다린다.   
    for (i = 0; i < 10; i++) 
    { 
        pthread_mutex_lock(&mutex); // 잠금을 생성한다. 
        printf("loop2 : %d\n", ncount); 
        ncount ++; 
        pthread_mutex_unlock(&mutex); // 잠금을 해제한다. 
        sleep(2); 
    } 
}     
 
int main() 
{ 
    int       thr_id; 
    pthread_t p_thread[2]; 
    int status; 
    int a = 1; 
 
    ncount = 0; 
    thr_id = pthread_create(&p_thread[0], NULL, do_loop, (void *)&a); 
    sleep(1); 
    thr_id = pthread_create(&p_thread[1], NULL, do_loop2, (void *)&a); 
 
    pthread_join(p_thread[0], (void *) &status); 
    pthread_join(p_thread[1], (void *) &status); 
 
    status = pthread_mutex_destroy(&mutex); 
    printf("code  =  %d", status); 
    printf("programing is end"); 
    return 0; 
} 
위의 코드를 우선 mutex 잠금을 하지 않은체 컴파일후 실행해보자. 간단하게 pthread_mutext_lock 와 pthread_mutex_unlock 부만 주석처리하면 된다. 그러면 do_loop2 와 do_loop 가 일정한 간격을 두고 ncount 자원에 접근하는 것을 볼수 있을것이다. 그러나 우리는 do_loop 가 ncount 자원을 접근하고 있는동안 다른 쓰레드가 접근하지 않기를 원할때가 있을것이다. 이럴때 뮤텍스 잠금을 사용하면 된다.

위의 코드에서 뮤텍스 잠금 부분의 주석을 풀고 다시 컴파일해서 실행시켜보면, do_loop 쓰레드가 ncount 증가 작업을 모두 마칠때까지 do_loop2 쓰레드는 해당 영역에서 블럭됨을 알수 있을것이다. 이런식으로 하나의 쓰레드가 특정자원에 접근할때 다른 쓰레드가 접근하지 못하도록(한번에 하나의 쓰레드만 해당 자원에 접근할수 있도록) 제어할수 있다.

컴파일 방법은 gcc -o mutex_lock mutex_lock.c -lpthread 이다

더이상 뮤텍스를 사용할일이 없다면 pthread_mutex_destory 를 이용해서 뮤텍스 자원을 제거(free) 하도록 한다. 만일 뮤텍스자원을 사용하는 쓰레드가 하나라도 존재한다면 에러코드(EBUSY)를 리턴한다. 그러므로 모든 쓰레드의 뮤텍스에 대해서 pthread_mutex_unlock 을 이용해서 잠겨져야만 뮤텍스 제거가 성공할수 있다. 성공할경우 0을 넘겨준다.

category_system
programing

http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Thread/Beginning/WhatThread


개요 

SMP와 같은 shared memory multiprocessor architectures에서 thread는 병렬화를 달성하기 위해서 사용된다. 쓰레드 구현은 하드웨어 벤더에서 그들자신의 필요에 의해서 만들어서 사용했으며 후에 소프크웨어 개발자들이 간단하게 사용할 수 있도록 작성하게 되었다. UNIX(:12)에서는 C(:12) 언어를 위한 표준 thread 프로그래밍 인터페이스를 사용하는데, IEEE POSIX 1003.1c 에 그 표준이 정의되어 있다. 이를 POSIX Thread 라고 부르게 되었고, 더욱 줄여서 pthread 라고 부르고 있다.

이 문서는 thread의 개념에 대해서 간단히 설명하고, 그 구현물인 pthread를 이용한 병렬처리 프로그래밍 기법에 대해서 설명할 것이다.

쓰레드는 무엇이며, 왜 이용하는가 

쓰레드는 세미(semi)프로세스, 혹은 Light Weight 프로세스라고 불리우며, 여러개의 클라이언트를 처리하는 서버/클라이언트 모델의 서버프로그래밍 작업을 위해서 주로 사용된다. 비슷한 일을 하는 fork(2) 에 비해서 빠른 프로세스 생성 능력과, 적은 메모리를 사용하는게 Light Weight 프로세스라고 불리우는 이유이다.

보통의 유닉스 프로세스는 main()함수에 의해서 시작되고 실행되는 single 쓰레드 로 이루어지며, 하나의 연속된 명령어들만을 처리한다. 반면 멀티쓰레드 프로그램은 여러개의 연속된 명령어들을 동시에 처리할수 있다.

스레드는 자기자신의 스택메모리영역을 가지고, 코드의 조각을 실행한다. 실(real) 프로세스 와는 달리 쓰레드는 다른 형제 쓰레드들과 메모리를 공유하게 된다.(보통 프로세스는 자기자신만의 메모리영역을 가진다). 이렇듯 전역 메모리를 공유하게 되므로 fork 방식에 비해서 좀더 작은 메모리를 소비하게 된다.

fork 에 비해서 thread 가 가지는 장점은 위에서 언급했듯이 "빠른 프로세스 생성" 능력과, 메모리 공유에 위한"적은 메모리의 사용"과 메모리 공유에 따른 쓰레드간의 좀더 쉬운 정보공유이다. fork(2) 시스템에서 부모와 자식같이 통신을 위해서는 IPC(:12)를 사용해야 하며 이는 꽤 어려운 작업이 될수도 있는데, 메모리를 공유함으로 IPC의 사용을 줄이면서도 쓰레드간 정보교환을 쉽게 할수있다.

아래는 fork()를 이용한 프로세스 생성과 pthread_create()를 이용한 thread 생성간의 비용을 비교한 표이다.
Platformfork()pthread_create()
realusersysrealusersys
AMD 2.4 GHz Opteron (8cpus/node)41.0760.089.010.660.190.43
IBM 1.9 GHz POWER5 p5-575 (8cpus/node)64.2430.7827.681.750.691.10
IBM 1.5 GHz POWER4 (8cpus/node)104.0548.6447.212.011.001.52
INTEL 2.4 GHz Xeon (2 cpus/node)54.951.5420.781.640.670.90
INTEL 1.4 GHz Itanium2 (4 cpus/node)54.541.0722.222.031.260.67

fork 에 비해서 쓰레드가 더 빠른 수행능력을 보이는 이유는 fork 가 기본적으로 모든 메모리와 모든 기술자(파일기술자등)을copy-on-write 방식으로 자식에게 복사하는데 비해서 쓰레드는 많은 부분을 공유하기 때문이다. copy-on-write 자체가 효율적이긴 하지만, 메모리 자원을 공유하는 것보다는 느릴 수 밖에 없다.

아래는 쓰레드 생성과 프로세스 생성의 성능에 대한 또다른 자료다.

http://www.ibm.com/developerworks/kr/library/l-rt7/c07-fig1.gif

http://www.ibm.com/developerworks/kr/library/l-rt7/c07-fig2.gif


반면 단점도 가지고 있는데, 모든 쓰레드가 같은 메모리 공간을 공유하게 되므로, 하나의 쓰레드가 잘못된 메모리연산을 하게 되면, 모든 프로세스가 그 영향을 받게 된다는 것이다. fork 등을 통한 프로세스 생성방식에 있어서는 OS(:12) 가 가각의 프로세스를 보호해줌으로 한 프로세스의 문제는 해당 프로세스의 문제로 끝나게 된다. 그러나 쓰레드는 이러한 프로세스 보호를 기대할수 없다. 하나의 쓰레드에 문제가 생기면 전체 쓰레드에 문제가 생길가능성이 크다. 이런 이유로 멀티 쓰레드 프로그램은 좀더 주의를 기울여서 작성해야 한다. 또단 하나의 흐름을 가지는 단일 프로세스 프로그램과 달리, 여러개의 흐름으로 분리가 되기 때문에, 디버깅을 하기가 까다롭다는 문제도 가진다.

쓰레드의 일반적인 개념을 정리했다.
  • 기술적으로 thread는 운영체제(:12)에서 스케쥴링이 가능한 독립된 명령(instructions)흐름의 단위이다. 여기에서 독립된 명령 단위를 보통 문맥이라고 표기한다. 스케쥴링 가능한 문맥 혹은 코드조각 으로 이해하면 될 것 같다.
  • 소프트웨어 개발자에게 있어서 thread는 main 프로그램으로 부터 독립적으로 실행될 수 있는 procedure로 보는게 이해가 더 쉬울 수 있을 것 같다.
  • main 프로그램은 여러개의 독립적으로 실행 가능한 프로시져 즉 쓰레드를 포함할 수 있는데, 이들을 동시에 운용할 경우 이를 multi thread 프로그램이라고 한다. 

아래는 쓰레드간에 서로 공유하는 자원들을 나열한 것이다.
  • 작업디렉토리
  • 파일지시자들
  • 대부분의 전역변수와 데이타들
  • UID 와 GID
  • signal
다음은 각각의 쓰레드가 고유하게 가지는 자원들을 나열한 것이다.
  • 에러번호(errno)
  • 쓰레드 우선순위
  • 스택
  • 쓰레드 ID
  • 레지스터 및 스택지시자
다음은 멀티쓰레드 프로세스가 어떻게 각종 자원을 공유하는지를 나타낸것이다.

http://www.joinc.co.kr/albums/album01/abg.gif

파일은 기본적으로 공유하며, 메모리 영역중에 상당부분을 공유한다는걸 볼수 있을것이다.

thread 프로그래밍의 주요 요소들 

병렬 프로그래밍 

최그들어 - 2009년 11월 현재 - 멀티 cpu 컴퓨터가 일반적으로 사용되는 추세로 접어들고 있다. 과거에는 기업에서 운용하는 서버급 컴퓨터에서나 multi cpu를 볼 수 있었지만 이제 개인 PC도 multi cpu를 사용하는걸 어렵지 않게 볼 수 있다. multi cpu가 사용되면서, 병렬프로그래밍 기법의 중요성이 더욱 커지고 있다.

하지만 병렬프로그램의 작성에는 고려해야할 여러가지 사항들이 있다. 때때로 이들은 프로그램의 작성을 매우 어렵게 만들기도 한다.
  • 로드 밸런싱
  • Data dependencies
  • 동기화 그리고 race conditions
  • 메모리 이슈
  • IO 이슈
  • 프로그램의 복잡도 증가
  • 개발시간과 비용의 증가 

일반적으로 사용되는 쓰레드 프로그램 모델은 다음과 같다.
  • Manager/worker boss/worker 모델이라고 부르기도 한다. 일반적으로 Manager 쓰레드가 모든 입력을 제어하고 각 쓰레드에 작업을 배분한다. server & client 모델을 사용하는 네트워크 프로그램의 제작에 널리 사용된다. Manager 쓰레드에서 client의 accept를 받아들이고 새로운 worker 쓰레드를 생성해서 input (연결)을 전달하는 방식이다.
  • pipeline task가 여러개의 suboperation 으로 나뉘어서 수행이 된다. 각 task가 처리한 결과를 다음 task에 넘겨서 처리하고 최종적으로 main thread는 완전히 처리된 데이터를 넘겨받는 식이다. 입력데이터가 long stream 일 경우에 사용할 수 있다. 자동차 조립 라인과 비슷하다. 조립라이을 컨테이너 벨트식으로 만들게 됨으로 실제 조립라인에는 여러대의 자동차가 존재하게 된다.
  • peer Manager/worker 모델과 비슷하다. 그러나 main 쓰레드는 단지 새로운 쓰레드를 생성하기만 한다. 생성된 쓰레드가 독립적으로 자신의 작업을 수행한다. 네트워크 프로그래밍으로 보자면, 각각의 생성된 쓰레드가 client accept()를 기다리는 방식이라고 보면 된다. 

shared memory 모델 

모든 쓰레드가 전역 메모리공간을 공유하는 방식이다. 프로그래머는 전역 메모리 공간에 대한 Access 동기화에 특시 신경을 써줘야 한다. 이들 공간에 대해서

thread safeness 

쓰레드는 공유하는 메모리공간에 대해서 서로 제어권을 얻기위해서 경쟁하는 상태에 놓일 수 있다. 이들 쓰레드가 자원을 놓고 경쟁하는 것을 제어하지 않으면 쓰레드가 안전 - safeness - 하지 않은 상태에 놓이게 된다.

예를들어 여러개의 쓰레드가 동일한 library(:12) 루틴을 이용해서 다음과 같은 작업을 한다고 가정해보자.
  1. 라이브러리가 메모리의 전역 구조체를 엑세스 한다.
  2. 거의 같은 시간에 쓰레드가 전역 구조체의 데이터를 읽고/쓰려고 한다.
  3. 이때 보호하고자 하는 데이터영역에 대한 동기화장치가 마련되어 있지 않았다면, thread:::safe(:12) 하지 않은 라이브러리가 된다.
이 문제는 멀티쓰레드 프로그래밍시 발생하게 되는데, 100% thread-safe 하지 않은 외부라이브러리를 사용하게 될경우 프로그램에 문제가 발생할 수 있다. 외부 라이브러리를 사용할때는 thread-safe 한지를 확인해볼 필요가 있다. 대부분의 잘 정의된 라이브러리는 thread-safe 한지를 명시하고 있다.

POSIX thread 

흔히 Pthread 라고 불리우며, POSIX(:12) 에서 표준으로 제안한 thread 함수모음으로 thread 를 지원하기위한 C(:12) 표준 라이브러리 셋을 제공한다. 이후 모든 예제는 Pthread 를 통해서 구현하고 설명하게 될것이다.

쓰레드의 생성과 종료 

멀티 쓰레드 프로그램이 처음 시작되었을때 그것은 main()함수를 실행하는 단일 프로세스 상태로 작동하게 될것이다. 이것은 그 자체로 하나의 완전한 쓰레드이다. 이 상태에서 우리는 pthread_create(3) 함수를 부름으로써 새로운 쓰레드를 생성할수 있다.

쓰레드를 이용한 프로그램은 기본적으로 아래와 같은 순서로 작동하게 된다.
     Master Thread
           |
           |             pthread_create() 에 의해서 worker 생성
           |
     +---+----+---+      worker 시작
     |   |    |   |
     |   |    |   |      각각의 worker는 그들의 작업을 수행한다.
     |   |    |   |
     +---+----+---+      worker 를 종료한다.  
           |
           |             pthread_join()에 의해서 worker 를 join 한다.
           |
     Master Thread

worker 은 쓰레드로 바꾸어 생각할수도 있다.

아래는 쓰레드 프로그램의 가장 간단한 예이다.
#include <stdio.h> 
#include <unistd.h> 
#include <pthread.h> 

void* do_loop(void *data)
{
    int i;

    int me = *((int *)data);
    for (i = 0; i < 10; i++)
    {
        printf("%d - Got %d\n", me, i);
        sleep(1);
    }
}

int main()
{
    int       thr_id;
    pthread_t p_thread[3];
    int status;
    int a = 1;
    int b = 2;      
    int c = 3;      

    thr_id = pthread_create(&p_thread[0], NULL, do_loop, (void *)&a);
    thr_id = pthread_create(&p_thread[1], NULL, do_loop, (void *)&b);
    thr_id = pthread_create(&p_thread[2], NULL, do_loop, (void *)&c);

    pthread_join(p_thread[0], (void **) &status);
    pthread_join(p_thread[1], (void **) &status);
    pthread_join(p_thread[2], (void **) &status);

    printf("programing is end\n");
    return 0;
}

위의 프로그램을 컴파일 시키기 위해선 pthread 라이브러리를 링크시켜줘야 한다.
[yundream@localhost test]# gcc -o thread thread.c -lpthread
최초에 main() 쓰레드가 시작되고 나서 pthread_create 를 이용해서 3개의 쓰레드를 생성 시켯다. 각각의 쓰레드는 do_loop 코드를 실행한다. 쓰레드가 모든 작업을 마쳤다면, pthread_join 을 이용해서 다른 쓰레드가 종료될때까지 기다리고, 모든 쓰레드가 종료되었다면, main()쓰레드가 종료되고 프로세스는 완전히 끝나게 된다.

쓰레드의 생성은 pthread_create()를 호출함으로써 이루어진다. 첫번째 아규먼트는 pthread_t 데이타 구조체에 대한 포인터를 돌려주는데, 쓰레드에 대한 지시값이 들어 있다. 각각의 쓰레드는 각각의 유일한 pthread_t 를 가지고 있어야만 한다. 위의 프로그램에서 우리는 각각의 쓰레드가 유일한 p_thread 를 가지도록 하기 위해서 생성할 쓰레드의 수만큼(3)을 배열로 만들었다. 2번째 아규먼트는 쓰레드가 만들어질때의 타입이다.

(스케쥴링 우선순위 같은). 보통은 NULL 값을 사용한다. 쓰레드 타입에 대한 내용은 pthread_attr_init(3) 을 참조하기 바란다. 3번째 아규먼트가 바로 쓰레드가 실행할 코드이다. 4번째 아규먼트는 쓰레드에 넘겨주고 싶은 값을 명시해주면 된다. 여기에서는 각 쓰레드에 번호를 부여하기위한 int 값을 넘겼다.

각 쓰레드는 1부터 10까지 증가 시킨다음에 쓰레드를 종료하도록 되어 있다.

그동안 메인 쓰레드는 pthread_join 을 호출하여서 각각의 쓰레드가 종료할때까지 기다린다. 3개의 쓰레드가 모두 종료가 된다면 메인 쓰레드는 "programing is end" 메시지를 출력하고 프로그램을 완전히 종료하게 될것이다.

pthread_join 은 fork 의 wait(2) 와 비슷하다고 볼수 있다. fork 에서도 자식프로세스가 모두죽고 나서 부모프로세스가 죽어야 하듯이(예외를 만들수도 있지만), 쓰레드도 모든 생성된 쓰레드가 종료된 다음에 메인 쓰레드가 종료되어야 한다.

pthread_join 을 사용하게 되면 메인 쓰레드는 pthread_join 에 명시된 쓰레드가 종료할때까지 잠자면서(sleep)기다리게 된다. 이는 모든 쓰레드가 종료하기 전에 부모쓰레드가 종료하는 사태를 막기 위해서 사용된다. 하나의 쓰레드가 모든일을 종료하고, pthread_join 을 깨우게 되면, 쓰레드가 가지고 있던 자원들을 모두 되돌려주게 된다 (free). 만약 실행되고 있는 쓰레드를 즉시 중지하길 원한다면 pthread_cancel() 과 pthread_testcancel()을 사용하면 된다.

공용으로 사용되는 자원의 동기화 

위에서 우리는 쓰레드를 사용할경우 상당히 많은 자원을 서로 공유하게 됨으로 얻는 여러가지 이점에 대해서 알아봤었다. 그러나 하나의 자원을 여러개의 쓰레드가 동시에 공유하게 됨으로 자원획득에 관한 문제가 발생할수 있다. 실지로 쓰레드를 사용하게 될경우 가장 주의해야 할점 중 하나가 바로 자원의 동시 접근에 대한 제어이다.

기본적으로 하나의 쓰레드가 하나의 자원에 접근하고 있을때, 다른 쓰레드는 그 자원에 대한 이전 쓰레드의 작업이 모두 끝나기전엔 접근하면 안될것이다.

이런한 공유되는 자원에 대한 접근제어는 IPC 설비의 세마포어와 매우 비슷한 점이 있다. 쓰레드에서는 이러한 공유되는 자원의 접근 제얼르 위해서 Mutexe 라는 것을 제공한다. Mutexe 는 다루어야할 내용이 꽤 많음으로 다음번 강좌에서 다루도록 하겠다.
category_system
programing

'리눅스 서버에 대해서 > 솔라리스(UNIX) 관련' 카테고리의 다른 글

솔라리스에서 파일 첨부  (0) 2013.01.09
UNIX 뮤텍스  (0) 2013.01.09
솔라리스 기본 설정 (텍스트)  (0) 2013.01.04
솔라리스 pkg 설치.  (0) 2013.01.04
솔라리스 11 설치  (0) 2012.12.08

Solaris  Basic  Set

  

  **  네트워크  설정  **

  

/etc/hosts

  127.0.0.1              localhost

  192.168.211.20      solaris10  loghost

  

/etc/hostname.pcn0

  solaris10

  

/etc/netmasks

  192.168.211.0          255.255.255.0

  

/etc/defaultrouter

  192.168.211.2

  

        -  부팅시  GW자동인식이  안돼면
            /etc/init.d/inetsvc

            route  add  default  route_IP  1    
    

/etc/resolv.conf
nameserver  219.250.36.130

  

/etc/nsswitch.conf
hosts:        files  dns

  

**  shell  바꾸기**                  

작업의  편의를  위해  root  의  쉘과  홈디렉토리부터  변경해준다.
솔라리스에서는  기본적으로  root  의  홈디렉토리를  /  로  사용하지만  관리의  편의를  위해  /root  라는  디렉토리를  만들어서  root  의  홈디렉토리로  사용한다.

  #  mkdir  /root
  
root의  기본  쉘을  bash로  변경해주고,  홈디렉토리를  /root  로  변경해준다.

  기본  :  root:x:0:1:Super-User:/:/sbin/sh

  변경  :  root:x:0:1:Super-User:/root:/bin/bash

/etc/bashrc와  root의  홈디렉토리에  .bash_profile  을  만들어준다.
  리눅스의  파일을  참조하여  사용한다.

  +++  /etc/bashrc  ++++++++++++++++++++++++++++++++++++++++

#  /etc/bashrc

#  System  wide  functions  and  aliases
#  Environment  stuff  goes  in  /etc/profile

#  by  default,  we  want  this  to  get  set.
#  Even  for  non-interactive,  non-login  shells.
if  [  $UID  -gt  99  ]  &&  [  "`id  -gn`"  =  "`id  -un`"  ];  then
        umask  002
else
        umask  022
fi

#  are  we  an  interactive  shell?
if  [  "$PS1"  ];  then
        case  $TERM  in
        xterm*)
                if  [  -e  /etc/sysconfig/bash-prompt-xterm  ];  then
                        PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm
                else
                        PROMPT_COMMAND='echo  -ne  "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"'
                fi
                ;;
        screen)
                if  [  -e  /etc/sysconfig/bash-prompt-screen  ];  then
                        PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen
                else
                PROMPT_COMMAND='echo  -ne  "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\033\\"'
                fi
                ;;
        *)
                [  -e  /etc/sysconfig/bash-prompt-default  ]  &&  PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default
                ;;
        esac
        #  Turn  on  checkwinsize
        shopt  -s  checkwinsize
        [  "$PS1"  =  "\\s-\\v\\\$  "  ]  &&  PS1="[\u@\h  \W]\\$  "
fi

if  !  shopt  -q  login_shell  ;  then  #  We're  not  a  login  shell
                for  i  in  /etc/profile.d/*.sh;  do
                if  [  -r  "$i"  ];  then
                        .  $i
                fi
        done
        unset  i
fi
#  vim:ts=4:sw=4

  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  +++  /etc/bashrc  ++++++++++++++++++++++++++++++++++++++++

#  .bash_profile

#  Get  the  aliases  and  functions
if  [  -f  /etc/bashrc  ];  then
                .  /etc/bashrc
fi

#  User  specific  environment  and  startup  programs

PATH=$PATH:$HOME/bin

export  PATH
unset  USERNAME

  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

-  다른  사용자의  shell  을  변경하고자  할때도  위와  같은  방법을  참고하여  변경해  준다.


**  솔라리스에서  한글  사용하기**

set  |  grep  LANG  으로  설정  확인
LANG=ko

변경은    /etc/profile  에


LANG=ko
export  LANG

  를  추가해  준다.


**  솔라리스에서  /home  사용하기**

  솔라리스에서는  /home을  automounter가  mount해서  사용하기  때문에  root라  할지라도  디렉토리나  파일을  만들  수  없다.  하지만  리눅스에  익숙한  관리자라면  /home  에서  모든  사용자  홈디렉토리를  관리하기를  원할  것이다.  /home  을  automount  하지  않으려면  /etc/auto_master파일에서  /home부분을  주석처리  하고  시스템을  재부팅하면  된다.

/etc/auto_master

......
+auto_master
/net                        -hosts                    -nosuid,nobrowse
#/home                      auto_home              -nobrowse
/xfn                        -xfn

reboot


**  시스템  시간  맞추기**

직접  맞추기
  
  rdate  명령어를  사용하여  필요할때마다  수정해도  좋지만,  이보다는  시스템  재부팅시에  자동으로  세팅되도록  부팅  스크립트에  포함시켜  준다.  time  서버로는  time.bora.net  또는  time.kriss.re.kr  를  사용한다.
  일단  현재  시간을  맞추기  위하여  프롬프트  상에서  한번  실행해  준다.  이때  리눅스에서는  -s  옵션을  주어  시스템  시간을  동기화  시키지만  솔라리스에서는  -s  옵션을  주지  않는  것을  주의한다.

rdate  time.bora.net

  다음  시스템  부팅시마다  자동으로  맞추기  위하여  부팅  스크립트에  포함시켜  준다.

  /etc/rc3
  …
rdate  time.bora.net

자동으로  맞추기

XNTP  라는  프로그램을  사용하면  시스템에  항상  XNTP  프로그램이  데몬으로  상주하며  자동으로  시스템  시간을  정확히  맞혀  준다  설정방법은

pkginfo  |  grep  ntp

NTP  패키지가  설치되어  있는지  확인하고,  설치되어  있으면

/etc/inet                          /  디렉토리로  이동하여,  ntp.client  파일을  ntp.conf라는  이름으로  복사한다.

ntp.conf  를  열어  맨  밑에

server  time.bora.net
server  time.nuri.net
server  gps.bora.net
server  ntp1.cs.pusan.ac.kr
server  ntp.ewha.net
server  ntp1.gngidc.net
server  ntp2.gngidc.net
server  time.kriss.re.kr

를  추가해  준다.

/etc/init.d/xntpd  start

다음  시스템  재부팅부터는  자동  실행된다

ntpq  -p

로  ntp  서버에  정상  접속하는지  확인한다.


**  DNS  설정  **

솔라리스에서  DNS  설정법은  리눅스와  약간의  차이가  있다.  먼저  리눅스처럼  resolv.conf  파일에  사용할  DNS  를  추가한다.  추가  방법은  동일하지만,  리눅스처럼  resolv.conf  파일이  생성되어  있는  것이  아니고,  시스템  관리자가  직접  생성해  줘야  한다.  위치는  리눅스와  같은  /etc/resolv.conf  가  된다.

resolv.conf

nameserver  211.115.194.2
nameserver  211.115.194.3
nameserver  203.255.112.34
search  localdomain

다음으로  nsswitch.conf  라는  파일을  열어서  hosts:  ….  줄의  맨  끝에  DNS를  추가해  준다.

nsswitch.conf

  …
hosts:            files  dns


**  패키지  다운로드  **

http://www.sunfreeware.com

  패키지  설치  확인은  아래의  명령어를  사용하여  확인한다.

pkginfo  |  grep  {Package  Name}

  패키지  설치법

  보통  솔라리스  패키지는  패키지명-패키지버전-OS버젼-cpu타입-local.gz  으로  제공된다.
  우선  gzip  을  사용하여  gz  압축을  해제후에  pkgadd  를  사용하여  설치한다.

ex)  gzip  -d  autoconf-2.59-sol9-intel-local.gz
    pkgadd  -d  autoconf-2.59-sol9-intel-local


**  컴파일  환경  만들기  **

wget  패키지를  미리  설치하여  다운로드에  사용한다
  
    ftp://ftp.sunfreeware.com/pub/freeware/intel/10/wget-1.10.2-sol10-x86-local.gz  
  
autoconf  패키지  설치

  wget  ftp://ftp.sunfreeware.com/pub/freeware/intel/10/autoconf-2.59-sol10-intel-local.gz

make  패키지  설치

  wget  ftp://ftp.sunfreeware.com/pub/freeware/intel/10/make-3.80-sol10-intel-local.gz


automake  패키지  설치

  wget  ftp://ftp.sunfreeware.com/pub/freeware/intel/10/automake-1.9-sol10-intel-local.gz

gcc  패키지  설치

  wget  ftp://ftp.sunfreeware.com/pub/freeware/intel/10/gcc-3.3.2-sol10-intel-local.gz

  

패키지는  일반적으로  /usr/local  ~  에  설치  되므로  /etc/profile  에  PATH와  LD_LIBRARY_PATH를  수정  또는  추가해  준다.

  /etc/profile

...

PATH=/usr/local/bin:$PATH
LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/usr/openwin/lib:/usr/openwin/bin:/usr/dt/lib:/usr/ucblib:/opt/lib:/usr/sfw/lib/:.
export  PATH  LD_LIBRARY_PATH

주의사항:
LD_LIBRARY_PATH에서  디렉토리  경로의  순서를  바꾸시면  안됩니다!  역시  PATH에서  /usr/local/bin이  앞에  나와야  합니다.


libgcc  패키지  설치

  wget  ftp://ftp.sunfreeware.com/pub/freeware/intel/10/libgcc-3.3-sol10-intel-local.gz

libiconv  패키지  설치

  wget  ftp://ftp.sunfreeware.com/pub/freeware/intel/10/libiconv-1.9.2-sol10-x86-local.gz


**  개발  환경  만들기**

  --  ls  하이라이팅  세팅

  솔라리스에  기본적으로  제공되는  ls  는  하이라이팅  기능을  지원하지  않으므로  fileutils에  포함되어  있는  ls를  사용하기  위하여  fileutils를  설치한다.
  현재  intel  기반  솔라리스용  fileutils  패키지를  제공하지  않으므로  앞서  세팅한  컴파일  환경을  사용하여  설치한다.

wget  http://ftp.gnu.org/pub/gnu/fileutils/fileutils-4.1.tar.gz
  
gzip  -d  fileutils-4.1.tar.gz
tar  xvf  fileutils-4.1.tar.gz

cd  ./fileutils-4.1

./configure

make
  make  시에  컴파일  에러가  난다면
  ........
  error:  parse  error  before  "ctid_t"  
  ........
  
  -  PATH  에  /usr/ccs/bin  가  추가되어  있는지  확인
  -  cd  /usr/local/lib/gcc-lib/sparc-sun-solaris2.10/3.3.2/install-tools
      ./mkheaders

  

make  install

  

설치가  완료되었다면,  /usr/local/bin  에  ls  가  설치되었는지  확인한다.

/usr/local/bin/ls  --color=auto

하이라이팅이  정상적으로  나타난다면,  쉘  스크립트에  alias  를  주어  사용한다.

/etc/profile
...
alias  ls  =  ‘/usr/local/bin/ls  --color=auto’


  --  vi  환경  설정

솔라리스에  기본적으로  제공되는  vi  는  하이라이팅  기능을  지원하지  않으므로  vim  을  설치하여  하이라이팅과  탐색  옵션  기능,  탭  설정  기능  등을  사용한다.

vim  패키지를  다운로드하여  설치한다.
wget  ftp://ftp.sunfreeware.com/pub/freeware/intel/10/vim-6.3-sol10-intel-local.gz

vim  패키지를  사용하기  위해  ncurses  패키지를  다운로드하여  설치한다.
wget  ftp://ftp.sunfreeware.com/pub/freeware/intel/10/ncurses-5.4-sol10-intel-local.gz
  
정상적으로  설치되었는지  확인하여  본다.
vim

이때  라이브러리  에러가  난다면  /etc/profile의  LD_LIBRARY_PATH  에  /usr/sfw/lib/  가  포함되어  있는지  확인하여  본다.

정상적으로  실행되지만  vim  역시  하이라이팅  기능이  기본  설정이  아니다.  터미널을  ansi  표준으로  세팅하고,  vi  를  vim  으로  aliasing  하고,  vim  설정  파일을  각자의  홈  디렉토리에  생성하여  하이라이팅  on  한다.

/etc/profile
...
alias  vi='vim'
TERM=ansi
export  TERM

을  포함하여  준다.

  

기타  추가  aliasing

/etc/profile

....

alias  cp='cp  -i'
alias  l.='ls  -d  .[a-zA-Z]*  --color=tty'
alias  ll='ls  -l  --color=tty'
alias  ls='ls  --color=tty'
alias  mv='mv  -i'
alias  rm='rm  -i'
alias  vi='vim'
alias  which='alias  |  /usr/bin/which  --tty-only  --read-alias  --show-dot  --show-tilde'

  

그리고  각자의  홈  디렉토리에  .

/root/.vimrc

set  incsearch
set  hlsearch
set  laststatus=2
set  ts=4
set  sw=4
syn  on

[출처]  Solaris  설치  후  기본적인  설정|작성자  바람추적
[2008년  04월  01일  22:27:00  수정되었습니다.]
[본문링크] Solaris 설치 후 기본적인 설정

'리눅스 서버에 대해서 > 솔라리스(UNIX) 관련' 카테고리의 다른 글

솔라리스에서 파일 첨부  (0) 2013.01.09
UNIX 뮤텍스  (0) 2013.01.09
유닉스 Thread 시스템프로그래밍  (0) 2013.01.09
솔라리스 pkg 설치.  (0) 2013.01.04
솔라리스 11 설치  (0) 2012.12.08

소프트웨어의 관리 
솔라리스에서 사용할 수 있는 소프트웨어로는 솔라리스가 기본적으로 제공하는 소프트웨어와 운영체제에 포함돼 있지 않기 때문에 개별적으로 구입하거나 별도로 설치하는 소프트웨어가 있다. 

일단은 솔라리스에 미리 설치된 애플리케이션을 중심으로 각종 관리 방법을 알아보자. 솔라리스는 소프트웨어를 패키지라는 단위로 취급을 하는데, 일종의 애플리케이션을 위한 모든 객체를 묶어 놓은 단위라고 생각하면 된다. 솔라리스의 모든 내장 소프트웨어들은 모두 이런 패키지 기반의 관리가 이뤄진다. 

이를 위해 솔라리스는 다음과 같은 패키지 명령어를 제공한다. 

·새로운 패키지의 설치 : pkgadd 
·설치된 패키지의 삭제 : pkgrm 
·설치된 패키지의 정보 : pkginfo 
·패키지 세트의 작성 : pkgmk, pkgparam, pkgtrans 


소프트웨어 설치 확인 방법 
동일한 솔라리스라고 하더라도 어떤 버전은 아파치가 포함돼 있으며, 어떤 버전은 솔라리스 관리 콘솔을 기본으로 제공하는 등, 솔라리스도 버전에 따라 새로운 기능이 추가되고, 이에 따라 새로운 패키지들이 지속적으로 추가되고 있다. 따라서 관리자는 자신이 원하는 패키지가 이미 설치돼 있는지 미리 확인하는 작업이 필요하다. 

만약 원하는 패키지의 이름(혹은 keyword)을 알고 있다면 다음과 같은 방법으로 설치 여부를 확인할 수 있다. 

# pkginfo -i | grep -i apache 
system SUNWapchd Apache Web Server Documentation 
system SUNWapchr Apache Web Server (root) 
system SUNWapchu Apache Web Server (usr) 

또는 다음과 같은 방법으로도 가능하다. 

# pkginfo -x | grep -i apache 
SUNWapchd Apache Web Server Documentation 
SUNWapchr Apache Web Server (root) 
SUNWapchu Apache Web Server (usr) 

이 두가지 방식의 차이는 pkginfo의 옵션의 차이다. <-i>는 ‘fully installed package’의 정보를 제공하고, <-x>는 설치된 패키지의 헤더만을 뽑아 출력하는 옵션이다. 어쨌든 일단 아파치 웹 서버가 설치돼 있음을 확인했다. 이제 검색한 패키지의 구제적인 정보(예를 들면 소프트웨어 버전이나, 설치 날짜 등)를 확인하기 위해서는 앞에서 검색한 패키지 이름으로 다시 한번 pkginfo를 실행해 보자.


# pkginfo -x SUNWapchr 
SUNWapchr Apache Web Server (root) 
(sparc) 11.9.0,REV=2001.10.18.00.44 

# pkginfo -l SUNWapchr 
패키지 인스턴스: SUNWapchr 
이름: Apache Web Server (root) 
범주: system 
아카이브: sparc 
버전: 11.9.0,REV=2001.10.18.00.44 
기본 디렉토리: / 
판매자: Sun Microsystems, Inc. 
DESC: The Apache HTTP server program (root components) 
PSTAMP: sfw8120011018004615 
INSTDATE: Apr 11 2002 17:33 
HOTLINE: Please contact your local service provider 
상태: 설치 완료 
파일: 197 설치된 경로 이름 
      9 공유 경로 이름 
      5 연결된 파일 
      24 디렉토리 
      10 실행 가능 
      2995 블록이 사용됨 (추정치) 

앞의 두가지 예에서 알 수 있듯이 설치된 패키지의 버전만을 확인하는 것이라면 <-x> 옵션만으로도 충분하지만, 그 외의 정보를 확인하기 위해서는 <-l>이 유용하다. 앞의 예에서 ‘Apache Web server 11.0.0’이 SUNWapchr라는 패키지 이름으로 설치돼 있음을 알 수 있으며, <-l>로 확인한 정보에 의하면 설치일이 4월 11일임을 알 수 있다. 그런데 지금까지 알아본 명령은 패키지 단위로만 정보를 제공한다. 간혹 패키지 내의 구성 파일 이름과 설치된 디렉토리를 확인해야 할 경우가 있다. 이런 경우에는 패키지의 손상 여부를 확인하기 위한 pkgchk 명령을 통해 확인할 수 있다. 다음 예제를 살펴보자. 

# pkgchk -l | grep -i httpd.conf 
경로 이름: /etc/apache/httpd.conf-example 
경로 이름: /usr/apache/man/man3/Apache::httpd_conf.3 
경로 이름: /usr/apache/perl5/5.6.1/sun4-solaris/Apache/httpd_conf.pm 

따라서 이미 설치된 아파치 웹 서버를 구성하기 위해 httpd.conf가 어디에 있는지 확인할 때 유용하다. 또는 관련 파일을 알고 있지만, 이 파일이 어떤 패키지에 속해 있는지 알아야 하는 경우에는 다음과 같은 명령을 수행한다. 

#pkgchk -l -p /etc/apache/http.conf-example 
경로 이름: /etc/apache/httpd.conf-example 
형식: 일반 파일 
예상 모드: 0644 
예상 소유자: root 
예상 그룹: bin 
예상 파일 크기 (바이트): 37327 
내용의 예상 합계(1): 56610 
예상한 최종 수정: 10월 18 오후 04시 43분 02초 2001 
다음 패키지에서 참조함: 
      SUNWapchr 
      현재 상태: 설치됨 


Pkgchk는 설치된 패키지의 속성 변화를 감시하기 위한 명령이다. 따라서, 디스크 손상이나 혹은 악의적인 해킹에 의항 설치된 파일의 기초적인 변형이나 손상을 확인할 수 있다.


GUI 툴을 이용한 소프트웨어 설치 확인 
솔라리스의 기본 그래픽 환경에서 이 관리 툴을 실행하기 위해서는 (화면 1)에 있는 ‘관리 도구’를 실행하거나 콘솔에서 #swmtool을 실행한다. 혹은 솔라리스 8에서부터 새로 제공되고 있는 제품 레지스트리 관리 프로그램을 사용할 수도 있다. 

‘솔라리스 제품 레지스트리’의 실행은 (화면 1)에서 아이콘을 클릭하거나 #prodreg 명령을 직접 입력해 실행할 수 있다. 



설치되지 않은 새로운 소프트웨어(패키지)의 설치 
이미 설치된 패키지를 다시 설치하거나 새로운 패키지를 설치하는 경우를 위해서라도 패키지 설치 방법은 반드시 알아둬야 한다. 
새로운 패키지를 설치할 때 가장 일반적으로 사용하는 방법은 pkgadd 명령을 사용하는 것이다. 솔라리스를 위한 패키지는 하나의 파일로 아카이빙한 경우와 파일 시스템에 디렉토리로 제공되는 아카이빙되지 않은 경우의 두가지가 있다. 그러나 일반적으로 솔라리스 CD는 아카이빙되지 않은 모드로 CD에 담겨 있다. 




·패키지가 디렉토리 구조로 풀려있는 경우 
이런 경우에는 앞서 언급한 #swmtool이나 #prodreg와 같은 GUI 기반 프로그램을 사용하거나 혹은 콘솔 창에서 직접 디렉토리 사이를 이동하면서 pkgadd로 설치하는 방법이 있다. 다음 (화면 2)는 앞서 언급한 ‘솔라리스 제품 레지스트리’를 이용한 것이고, 다음은 swmtool을 이용한 방법이다. 

#swmtool -d /cdrom/cdrom0/s0 

반면 CD나 디스크에서 패키지가 있는 디렉토리를 직접 오가면서 설치해야 하는 경우에는 패키지가 들어있는 디렉토리에서 다음과 같이 실행함으로서 현재 디렉토리에 있는 모든 패키지의 목록을 보면서 선택적으로 설치할 수 있다. 

#pkgadd -d . 

한편 현재 디렉토리에서 설치할 패키지의 이름을 명확하게 아는 경우에는 설치시 아예 이름을 지정함으로써 보다 빠르게 실행할 수 있다. 

#pkgadd -d . SUNWapchr 

·패키지가 아카이빙돼 있는 경우 
예를 들어 사용자가 솔라리스가 기본적으로 제공하지 않는 GNU 패키지인 를 설치하고 싶은 경우가 있다고 하자. gzip으로 아카이빙하는 방식은 흔히 인터넷에서 패키지를 배포하기 위해 사용하는 형태다. lsof의 다운로드부터 설치까지의 과정은 다음과 같다.


#wget ftp://ftp.sunfreeware.com/pub/freeware/sparc/8/lsof-4.49-sol8-sparc-64-local.gz 
#gunzip lsof-4.49-sol8-sparc-64-local.gz 
#pkgadd -d lsof-4.49-sol8-sparc-64-local 

앞의 방법과 다른 것은 -d 뒤에 ‘.’이 없다는 것이다. 즉 패키지 파일을 -d의 부 파라메타로 입력하는 것이다. 참고로 앞에서 사용한 wget이란 유틸리티는 솔라리스에서 기본적으로 제공되지 않는다. 이같은 툴이 없는 경우에는 웹 브라우저나 FTP 클라이언트 프로그램으로 다운받을 수 있다. 

설치된 불필요한 소프트웨어의 삭제 
앞에서 언급된 방법으로 설치된 패키지의 정보를 얻었다면 이제 삭제도 할 수 있다. 일반적으로 삭제하는 경우는 그리 자주 발생하지 않지만, 새로운 버전을 설치하나 혹은 기존에 있던 패키지에 부분적으로 문제가 발생할 경우도 있으므로 패키지 삭제 방법도 알아둘 필요가 있다. 어쨌든 원하는 패키지의 삭제는 ‘#pkgrm SUNWapchr’과 같은 방식으로 이뤄진다.

Posted by 행복한 프로그래머 멋진상현

솔라리스라고... 유닉스 종류중 하나입니다.

보통 서버계열에서 많이 쓰고, 서버 프로그래머로서 그 원천을 모르면 안되겠다 싶어 설치해 보았습니다.

우선 필요한건 같은 회사에서 제작한 버츄얼 박스에 가상PC를 돌릴생각입니다.

 

솔라리스를 받는곳은

영화 메트릭스의 오라클씨에게.........

 

http://www.oracle.com/us/products/servers-storage/solaris/solaris11/overview/index.html?origref=http://www.oracle.com/us/products/servers-storage/solaris/index.html

 

여기서 얻을 수 있습니다. 간단한 ID무료 가입후 이미지 롬 파일을 다운 받습니다.

 

 

설치하는 방법입니다. 저는 그냥.... 같은 회사꺼인 버츄얼 박스를 사용했고요..

1. 새로 만들기를 눌러 새 가상 PC를 만듭니다.

 

 

2. 이름은 그냥... 현재(2012.12.08) 최신 버젼인 솔라리스 11을 선택합니다.

 

 

3. 램과 하드 디스크 만들기는 적당히 조절해 줍니다.

 

 

4. 가상  PC가 만들어 졌습니다. 이제 이걸로 부팅합니다.

 

 

5. 처음에 아무것도 없으니, 시동디스크를 넣어달라는 박스가 뜹니다. 거기서 오라클씨에게 다운받은 이미지를 선택합니다.

 

 

 

6. 음....부팅화면이 뜨네요... 그냥 맨 처음꺼로 선택합니다. 

 

 

7. 키보드랑. 언어를 선택하라고 합니다. 음... 자신있는 언어를 선택해 줍니다ㅋ

 

 

8. 이것은... gnome인터페이스!!!

 저는 솔직히 여기서 이게 끝인줄 알았습니다. 유분투나, 센토스(CentOS).. 리눅스 몇번 만져본 저로선 그놈이 뜨니... orz

 하지만 이건 그냥.... 설치화면의 일부분입니다. 바탕화면에 오라클 솔라리스 설치를 살포시 눌러줍시다.

 

 

 

9. 음.... 이 무슨 시츄레이션인지 몰라도 어쨋든 우리가 보고싶은 화면이 떳습니다...

초보자는 접근도 하지 말라는 간접 경고라 생각하고 다음을 누릅니다.

 

 

10. 설치화면에 대해선... 그냥 읽어보시면 될꺼 같아 자세한 언급은 안하겠습니다 (;;;;;;;)

 

 

 11. 설치를 다한 뒤 재부팅을 하는데 아까와 같은 화면이 나왔다면, 메인메뉴 장치-> CD/DVD장치에서 아까 선택한 설치 이미지롬의 마운트를 해제해 주고 다시 재부팅 시킵니다.

 

 

12. 음... 이제 원하던 화면이 떳습니다. 그냥 엔터!

 

 

 13. 아까 설치중 설정한 계정과 패스워드를 입력해 줍니다.

밑에 인터페이스가 있는데, 전 조금 편하게 그놈을 선택했습니다.

xterm 환경도 선택이 가능합니다.

 

 

14. 그럼 텅텅빈 유닉스가 맞아 줍니다... (아까랑 화면이 똑같은 그놈..)

여기서 바탕화면에 소프트웨어 추가로 원하던거 선택해서 설치를 해줍니다.

... 예를들어 gcc나.. make나... lib나....gedit,  vi 같은것을.... 

 

 

15. 음.... 여기서 받는 시간은 좀 오래 걸리는거 같더군요..

 여튼 400여 메가를 1시간 반정도에 다운받아 설치가 완료 되었습니다.

터미널을 열어서 gcc랑 vi가 있는지 확인했습니다.

 

이제 남은것은... vi!!!!!!!

음..... 해피해킹 키보드 단종됬는데.... 일본아마존 들어가서 해외구매로 구입해야 할꺼 같습니다. ㅠㅠ

 

+ Recent posts