Posts Tagged ‘linux’

Linux가 PC 용 OS가 되기 힘든점…

Monday, April 21st, 2008

개인적으로 리눅스를 상당히 좋아하는 편이다.

아마도 개발자 출신이라면 대부분 리눅스에 대한 어느정도 관심이 있을것이며 사용에도 무료인 OS가 이리도 부진하는데 의하하게 생각하는 사람도 많을줄 안다.

과거 DOS 시절이나 리눅스 정도는 아마도 국내 기술력이면 충분히 개발이 가능할것이다. 하지만 아마도 아무도 쓰지 않는 OS가 될것은 누구봐도 알수 있기 때문에 투자나 연구 개발이 힘든 분야다.

마이크로소프트의 OS 독주는 이 분야를 발전시킨다기 보다는 독점으로 인한 발전의 저해요인이 더 클것이라고 생각한다. 유일하게 매킨토시가 그 부분을 막고는 있지만 그 성향이 전문집단 위주로 되 있다보니 대중성에서 상당히 밀리는건 사실이다. 물론 미국에서는 많은 비율을 사용하기도 하고 맥을 사용하는 사용자는 그렇지 않다고 말할 수도 있지만 현실적으로 윈도우의 사용자 환경을 따라올수는 없는 실정이다.

처음으로 돌아가서 리눅스가 왜 PC용 OS가 되지 못할까? 맥이 기본으로 사용하는 OS가 리눅스와 비슷한 FreeLinux계열인걸로 봐서는 별로 어려운 문제가 아닐걸로 생각된다.

개인적으로 두가지의 문제가 리눅스가 사용자용으로 전환하지 못하는걸로 생각한다.

일단 개인사용자용 리눅스는 일반적으로 생각할때 무료다. 무료기 때문에 발전하지도 못할뿐더러 아무도 책임지지 않는점이다. 리눅스의 가격이 2,3만원정도로 저렴하게 책정해서 UI를 잘 만들었을때 경쟁력이 충분하다고 생각한다.

과거에는 많은 어플이나 오피스 프로그램등이 그 환경을 제한했지만 현재는 단지 웹브라우져만 잘 돌고 게임만 잘 돌아도 사용할수 있는 분야는 적어도 30%는 되지 않을까 생각된다.

두분째 문제는 SDK라고 생각한다. 좀더 확장해서 본다면 OCX, COM 등의 환경이다. 리눅스역시 이런게 불가능하지는 않지만 일반인이 개발하기에 매우 껄끄러운 부분이다 보니 브라우져만으로는 다양한 멀티미어 및 프로그램 처리가 어려운 점이다. SDK역시 OS를 배포하기 위한 아주 중요한 수단이라고 생각한다.

세상에 공짜가 없듯이 공짜는 그 값을 하는 것이다. 윈도우가 컴퓨터 H/W만큼이나 비싼점은 아무리 생각해도 지나침이 있다고 본다. 나 역시 S/W를 개발하는 입장이지만 MS의 가격정책에는 무리가 있다.

리눅스 진영의 공짜 정책은 결과적으로 MS의 독주를 막지 못하는 결과에 어느정도 기인하고 있다고 생각된다.

리눅스 데몬 개발 4/8

Thursday, April 21st, 2005

지난 3장까지는 기초적인 함수와 개녕이였고 이번 장부터는 실질 서버의 모습을 소개합니다.

첨부된 소스는 최소한의 코딩으로 만든 서버로 클라이언트가 접속한뒤 문자열을 송신하면 클라이어트에 받은 문자갯수를 돌려주고 종료하는 프로그램입니다.

테스트를 위해서는 telnet 을 클라이언트로 이용하시면 됩니다.
서버 기동시 포트번호를 파라메터로 입력하시면 되는데 주의할점은 1024 이하의 번호를 쓰기 위해서는 root로 로그인되어야 하고 이후번호의 경우는 무관합니다. linux의 기본 보안 정책이고..

tcp 서버를 만들기 위해서 가장 기본적으로 사용하는 함수는
socket, bind, listen, accept, recv, send, close

클라이언트라면
socket, connect, send, recv, close

서버의 경우는 bind, listen, accept 가 추가됩니다.

socket은 통신을 하기 위한 핸들을 생성하는 함수입니다.
파일 오픈과 동일한 기능이라고 생각하면 됩니다.
실재로 socket에서 리턴된 핸들에다 read, write와 같은 파일 명령으로 데이타를 송수신하여도 동일한 결과로 동작하게 됩니다.
close를 이용하는 걸 봐도 같다는걸 알수 있습니다.

bind는 뭔가를 묶는다는 뜻이므로 해당 어드레스와 포트를 시스템에게 예약하는 명령어입니다.

listen은 클라이언트가 젒속하도록 대기상태로 만드는 것입니다.
실제로 listen 이후부터는 클라이언트가 접속이 가능합니다.

일반적으로 listen( s, 5 )라고 5라는 숫자가 있는 리눅스의 기본 queue의 갯수가 5입니다. 변경할 필요도 없으면 크게 한다고 해서 실제로 커지지도 않습니다. 큐의 개념은 accept 로 빼내기전에 버퍼링되는 커넥션이라고 생각하면 됩니다.

accept라는것을 접속대기중인 클라이언트를 실제로 프로그램과 접속을 시켜주는 명령어입니다. accept의 리턴값이 소켓이고 새로운 소켓번호를 통해서 접속된 클라이언트와 송수신을 하게 되는 것입니다.

이후는 recv, read, send, write의 함수를 이용해서 통신을 하면됩니다.

샘플소스는 무조건 클라이언트를 기다라다가 접속이후 문자열을 기다리다가 문자열이 들어오면 문자열을 출력한뒤 클라이언트로 해당 문자열의 길이를 반환하고 종료하는 프로그랭입니다.

실제로 서버라기 보다는 수신 대기프로그램 및 수신 테스트 프로그램이라고 생각하면 됩니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>  

#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>  

int main( int argc, char *argv[] )
{
    if ( argc != 2 )
    {
        printf( "Usage : %s port
", argv[0] );
        return -1;
    }  

    struct sockaddr_in  addr;  

    memset( &addr, 0, sizeof(addr) );  

    addr.sin_addr.s_addr = htonl( INADDR_ANY );
    addr.sin_port = htons( atoi( argv[1] ) );  

    int s = socket( AF_INET, SOCK_STREAM, 0 );  

    if ( !bind( s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in) ) )
    {
        if ( !listen( s, 5 ) )
        {
            int S = accept( s, NULL, NULL );  

            if ( S != -1 )
            {
                char buff[1024];
                int  size;  

                memset( buff, 0, sizeof(buff) );
                size = read( S, buff, sizeof(buff) );  

                printf( "Read : %s
", buff );  

                sprintf( buff, "Read %d bytes
", size );
                write( S, buff, strlen(buff) );  

                close( S );
                printf( "Disconnect
" );
            }
            else
            {
                printf( "accept error
" );
            }
        }
        else
        {
            printf( "listen error
" );
        }
    }
    else
    {
        printf( "bind error
" );
    }  

    close( s );  

    return 0;
}

리눅스 데몬 개발 3/8

Monday, April 18th, 2005

3 장 : thread

많은 데몬 개발 또는 통신 프로그램에서 fork()를 많이 이용한다.
하지만 필자는 fork보다는 thread 를 더 선호하는 편이다.

fork()는 단순 클라이언트의 경우에 상당히 유리하고 간단하게 개발할 수 있는 반면에 클라이언트간에 데이타 공유나 전송에는 오히려 더 어려운 코딩을 해야 하기 때문이다.

fork()가 진정한 child프로세서를 만드는 기법이라면 thread는 윈도우의 개발 방식과 상당히 유사하기 때문에 윈도우 클라이언트와 연동하는 모델의 서버를 개발한다면 thread쪽을 더 권장한다.

thread 가 fork()와 가장 다른점은 함수단위의 스래드 처리가 가능하기 때문에 global 변수나 기타 다른 함수의 데이타 공유가 가능하다는 점이다. 하지만 이런한 편의성은 두 스래드간에 동시 자료 접근으로 인한 결함도 야기된다. 예를 들어 두 스래드가 동시에 트리 또는 큐같은 메모리를 사용하게 되면 데이타의 연결고리가 끝어질 수 있는 단접이 있다. 이런 경우에 이후에 설명할 예정인 세마포 또는 뮤택스와 같은 동기 함수를 이용하는 코딩 기법이 필요하게 된다.

이번 예제에서 가장 중요한 포인트는 cnt라고 하는 global변수가 fork()방식으로 했을때 parent와 child가 각각 다른 변수로 인식되는 반면 thread에서는 같은 변수로 사용이 되는 접을 알수 있는 소스다.

아래의 소스를 실행해보면 cnt가 중간에 바뀌고 나서 thread에서 출력시에도 바뀐 값을 똑같이 출력하는것을 확인 할 수 있다.

다중 타스크 프로그램에서 fork와 thread어느쪽이 정답이하고는 할수 없다.
그건 while 이냐 for 냐의 구분과 비슷할 것이다.
하지만 이 두 방식의 차이를 정확히 이해한다면 데몬 개발에서는 상당히 편리한 코딩을 할 수 있게 된다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

int cnt = 0;

void *fun( void *arg )
{
printf( “This is child : %d
“, getpid() );
sleep( 3 );
printf( “child end : %d
“, cnt );

pthread_exit( NULL );
return 0;
}

void main( int argc, char *argv[] )
{
pthread_t t;
pthread_create( &t, NULL, fun, NULL );

cnt = 10;

printf( “This is parent : %d
“, getpid() );
sleep( 5 );
printf( “server end : %d
“, cnt );
}

=============================
This is child : 12325
This is parent : 12323
child end : 10
server end : 10