'Language/C'에 해당되는 글 66건

  1. 2012.04.10 아스키 코드 0x00 ~ 0x20 까지
  2. 2012.04.06 How to print out thread id from pthread_t
  3. 2012.03.16 Programmiersprache C/C++
  4. 2012.03.16 getprocs64() (get process information on aix)
  5. 2012.03.15 fork, wait, waitpid, zombie(좀비)
  6. 2012.03.14 strerror
  7. 2012.03.09 bsearch() 함수 설명 및 알고리즘
  8. 2012.02.02 semget() 세마포어 생성 및 접근
  9. 2012.02.02 inet_ntoa 64bit 사용시 에러 대처방법
  10. 2012.01.30 FILE, fopen, fprintf, fflush, fclose

아스키 코드 0x00 ~ 0x20 까지

Language/C 2012. 4. 10. 14:57

0000 0000   000   000     00  NUL NULL 문자
0000 0001   001   001     01  SOH 헤더 시작(Start Of Header)
0000 0010   002   002     02  STX 본문 시작, 헤더 종료(Start of TeXt)
0000 0011   003   003     03  ETX 본문 종료(End of TeXt)
0000 0100   004   004     04  EOT 전송 종료, 데이터 링크 초기화(End Of Transmission)
0000 0101   005   005     05  ENQ 응답 요구(ENQuiry)
0000 0110   006   006     06  ACK 긍정응답(ACKnowledge)
0000 0111   007   007     07  BEL 경고음(BELl)
0000 1000   008   010     08  BS  박스페이스(BackSpace)
0000 1001   009   011     09  HT  수평 탭(Horizontal Tab)
0000 1010   010   012     0A  LF  개행(Line Feed)
0000 1011   011   013     0B  VT  수직 탭(Vertical Tab)
0000 1100   012   014     0C  FF  다음 페이지(Form Feed)
0000 1101   013   015     0D  CR  복귀(Carriage Return)
0000 1110   014   016     0E  SO  확장문자 시작(Shift Out)

0000 1111   015   017     0F  SI  확장문자 종료(Shift In)
0001 0000   016   020     10  DLE 전송제어 확장(Data Link Escape)
0001 0001   017   021     11  DC1 장치 제어(Device Control 1)

0001 0010   018   022     12  DC2 장치 제어(Device Control 2)
0001 0011   019   023     13  DC3 장치 제어(Device Control 3)

0001 0100   020   024     14  DC4 장치 제어(Device Control 4)
0001 0101   021   025     15  NAK 부정응답(Negative AcKnowledge)
0001 0110   022   026     16  SYN 동기(SYNnchronous idle)
0001 0111   023   027     17  ETB 전송블록 종료(End of Transmission Block)
0001 1000   024   030     18  CAN 개무시(CANcel)
0001 1001   025   031     19  EM  매체 종료(End of Medium)
0001 1010   026   032     1A  SUB 치환(SUBstitute)
0001 1011   027   033     1B  ESC 제어기능 추가(ESCape)
0001 1100   028   034     1C  FS  파일경계 할당(File Seperator)
0001 1101   029   035     1D  GS  레코드 그룹경계 할당(Group Seperator)
0001 1110   030   036     1E  RS  레코드경계 할당(Record Seperator)
0001 1111   031   037     1F  US  장치경계 할당(Unit Seperator)
0010 0000   032   040     20  SPC 스페이스(SPaCe)

'Language > C' 카테고리의 다른 글

execl 다른 프로그램 실행  (0) 2012.04.26
Why use select() instead of sleep()?  (0) 2012.04.26
How to print out thread id from pthread_t  (0) 2012.04.06
Programmiersprache C/C++  (0) 2012.03.16
getprocs64() (get process information on aix)  (0) 2012.03.16
:

How to print out thread id from pthread_t

Language/C 2012. 4. 6. 17:40

Frank Cusack wrote On 06/18/07 12:28,:
> On Mon, 18 Jun 2007 15:51:08 -0000 Bin Chen wrote:
>
>>On Jun 18, 11:44 pm, Herman.Schu...@gmail.com wrote:
>>
>>>Hi,
>>>
>>>I am trying to print out the thread id in my program.
>>> static pthread_t GetCurrentThreadID() { return :thread_self(); }
>>>
>>>void myFunction() {
>>>pthread_t id = GetCurrentThreadID();
>>>
>>> printf (" thread id %d\n", id);
>>>
>>>}
>>>
>>>But I get a negative number: -122112944. Did I do something wrong?
>>>Why the number is negative?

>
>
> Because %d is an integer type and prints both positive and negative
> numbers. The thread id happens to be very large and is treated as a
> negative integer.
>
>
>>The pthread_t is defined as an unsigned variable,

>
>
> No it isn't. It's an opaque type.
>
> printf("%lu\n", (unsigned long) id);


And even that won't always work: pthread_t is *really*
opaque, and need not be a type to which a cast operator can
be applied. On at least one implementation, pthread_t is
a struct.

--
Eric.Sosman@sun.com


http://fixunix.com/unix/84437-how-print-out-thread-id-pthread_t.html

'Language > C' 카테고리의 다른 글

Why use select() instead of sleep()?  (0) 2012.04.26
아스키 코드 0x00 ~ 0x20 까지  (0) 2012.04.10
Programmiersprache C/C++  (0) 2012.03.16
getprocs64() (get process information on aix)  (0) 2012.03.16
fork, wait, waitpid, zombie(좀비)  (0) 2012.03.15
:

Programmiersprache C/C++

Language/C 2012. 3. 16. 18:10

 http://www.imb-jena.de/~gmueller/kurse/c_c++/escfolge.html 

Beispielfolge 6

Anwendung von ANSI-Escape-Steuerfolgen


Beispiel 1: 
Realisierung einiger Funktionen zur Arbeit mit Bildschirm und Cursor - Variante 1

  #include <stdio.h>
  
  #define ESC 27
  
  void home(void)
  {
    printf("%c%s", ESC, "[1;1H");
  }
  
  void cursor(unsigned zeile, unsigned spalte)
  {
    printf("%c%c%02d%c%02d%c", ESC, '[', zeile, ';', spalte, 'H');
  }
  
  void store_cursor(void)
  {
    printf("%c%s", ESC, "[s");
  }
  
  void reset_cursor(void)
  {
    printf("%c%s", ESC, "[u");
  }
  
  void color(unsigned bg, unsigned fg)
  {
    printf("%c%c%02d%c%02d%c", ESC, '[', bg, ';', fg, 'm');
  }
  
  void colour(unsigned bg, unsigned fg, unsigned fmt)
  {
    printf("%c%c%02d%c%02d%c%1d%c", ESC, '[', bg, ';', fg, ';', fmt, 'm');
  }
  
  void normal()
  {
    printf("%c%s", ESC, "[0m");
  }
  
  void clear(void)
  {
    printf("%c%s", ESC, "[2J");
    home();
  }
  
  void bell(int n)
  {
    int i;
    for ( i=0; i<n; i++)
      printf("%c", 7);
  }
  
  int main(void)
  {
    clear();
    printf("Das ist links oben !\n");
    store_cursor();
    cursor(2,2); printf("2,2");
    color(1,1);
    cursor(22,22); printf("22,22");
    (void)getchar();
    reset_cursor();
    colour(32,40,7);
    printf("ENDE");
    color(30,42);
    (void)getchar();
    bell(5);
    normal();
  
    return 0;
  }

Beispiel 2: 
Realisierung einiger Funktionen zur Arbeit mit Bildschirm und Cursor - Variante 2

  #include <stdio.h>

  void home(void)
  {
    printf("\033[1;1H");
  }
  
  void cursor(unsigned zeile, unsigned spalte)
  {
    printf("\033[%02d;%02dH", zeile, spalte);
  }
  
  void store_cursor(void)
  {
    printf("\033[s");
  }
  
  void reset_cursor(void)
  {
    printf("\033[u");
  }
  
  void color(unsigned bg, unsigned fg)
  {
    printf("\033[%02d;%02dm", bg, fg);
  }
  
  void colour(unsigned bg, unsigned fg, unsigned fmt)
  {
    printf("\033[%02d;%02d;%1dm", bg, fg, fmt);
  }
  
  void normal()
  {
    printf("\033[0m");
  }
  
  void clear(void)
  {
    printf("\033[2J\033[1;1H");
  }
  
  void bell(int n)
  {
    int i;
    for ( i=0; i<n; i++)
      printf("\a");
  }
  
  int main(void)
  {
    /* analog wie bei Variante 1 */
  }
Variante 2 ist im Vergleich zur Variante 1 effektiver programmiert, der Quelltext ist jedoch schwerer zu lesen.


Beispiel 3: 
Realisierung einiger Makros zur Arbeit mit Bildschirm und Cursor

  #include <stdio.h>

  #define HOME           printf("\033[1;1H")
  #define STORE_CURSOR   printf("\033[s")
  #define RESET_CURSOR   printf("\033[u")
  #define NORMAL         printf("\033[0m")
  #define CLEAR          printf("\033[2J\033[1;1H")
  
  #define CURSOR(zeile,spalte)  printf("\033[%02d;%02dH", zeile, spalte)
  #define COLOR(bg, fg)         printf("\033[%02d;%02dm", bg, fg)
  #define COLOUR(bg, fg, fmt)   printf("\033[%02d;%02d;%1dm", bg, fg, fmt)
  #define BELL(n)        do {                                     \
                            int i;                                \
                            for ( i=0; i<n; i++)                  \
                              printf("\a");                       \
                            }                                     \
                         while ( 0 )
  
  int main(void)
  {
    CLEAR;
    printf("Das ist links oben !\n");
    STORE_CURSOR;
    CURSOR(2,2); printf("2,2");
    COLOR(1,1);
    CURSOR(22,22); printf("22,22");
    (void)getchar();
    RESET_CURSOR;
    COLOUR(32,40,7);
    printf("ENDE");
    COLOR(30,42);
    (void)getchar();
    BELL(5);
    NORMAL;
  
    return 0;
  }
Die Anwendung von Makros anstelle von Funktionen führt noch einmal zu effektiverem Code. 
Funktionen bieten jedoch einen besseren Schutz gegenüber falscher Anwendung als Makros !


Vergleich der Programmgrößen

               AIX xlc   AIX gcc
  Beispiel 1      5462      6920
           2      4910      6348
           3      4006      4850

'Language > C' 카테고리의 다른 글

아스키 코드 0x00 ~ 0x20 까지  (0) 2012.04.10
How to print out thread id from pthread_t  (0) 2012.04.06
getprocs64() (get process information on aix)  (0) 2012.03.16
fork, wait, waitpid, zombie(좀비)  (0) 2012.03.15
strerror  (0) 2012.03.14
:

getprocs64() (get process information on aix)

Language/C 2012. 3. 16. 16:54
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <procinfo.h>
#include <sys/time.h>
#include <sys/procfs.h>

/* Macro to hide time maths */
#define TIMED(member) ((double)(procs[i].member.tv_sec+ procs[i].member.tv_usec/1000000.0))

/*
int getprocs64 ( struct procentry64 *ProcessBuffer, int ProcessSize, struct fdsinfo64 *FileBuffer, int FileSize, pid_t *IndexPointer, int Count);
*/

main(int argc, char **argv)
{
pid_t firstproc = (pid_t)0;
struct procentry64 *procs;
struct psinfo ps;
int actual_processes;
int initial_processes;
int i;
char filename[64];
int fd;
int count;

firstproc = 0;
initial_processes = getprocs64(NULL, 0, NULL, 0, &firstproc, 999999);
procs = malloc( initial_processes * sizeof(struct procentry64) );

firstproc = 0; /* you have to reset this every time */
actual_processes = getprocs64(procs, sizeof(struct procentry64), NULL, 0, &firstproc, initial_processes);

printf("PID,CPU-Time,Memory,Threads,Status,Start,UID,Command,CMD-Arguments\n");

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

sprintf(ps.pr_psargs, "data missing", 12);
sprintf(filename, "/proc/%d/psinfo", procs[i].pi_pid);
/*printf("opening file %s\n",filename);*/
fd=open(filename, O_RDONLY);
if(fd == -1) {
perror("open failure");
} else {
count = read(fd,&ps,sizeof(struct psinfo));
if(count != sizeof(struct psinfo)) {
perror("read failure");
printf("count was %d expected %d\n", count, sizeof(struct psinfo));
}
close(fd);
}

/* patch up weird commands */
if(procs[i].pi_pid == 0) strcpy(procs[0].pi_comm, "Swapper");
if(procs[i].pi_state == SZOMB)
strcpy(procs[i].pi_comm, "><defunct Zombie>");
if(!strcmp("gil", procs[i].pi_comm))
strcpy(procs[i].pi_comm, "gil = TCP/IP");

printf("%d,%0.0f,%d,%d,%d,%d,%d,%s,%s\n",
   (int)procs[i].pi_pid,
   (double) (TIMED(pi_ru.ru_utime) +TIMED(pi_ru.ru_stime)),
   (int)procs[i].pi_size*4, /* convert pages to KBytes */
   (int)procs[i].pi_thcount,
   (int)procs[i].pi_state,
   (int)procs[i].pi_start,
   (int)procs[i].pi_uid,
   procs[i].pi_comm,
   ps.pr_psargs
   );
}
}

=========================================================================================================
#include <stdio.h>
#include <stdlib.h>
#include <procinfo.h>
#include <sys/types.h>

int
main(argc, argv)
int argc;
char *argv[];
{
        struct procentry64 psinfo;
        pid_t pid;
        if (argc > 1)
                pid = atoi(argv[1]);
        else
                pid = getpid();

        printf("My pid: %d\n", pid);

        if (getprocs64(&psinfo, sizeof(struct procentry64), NULL, sizeof(struct fdsinfo64) , &pid, 1) > 0) {
                printf("Pid: %d\n", psinfo.pi_pid);
                printf("Up start: %lld\n", psinfo.pi_start);
                printf("Program name: %s\n", psinfo.pi_comm);

                return 0;
        } else {
                perror("getproc64");
                return 1;
        }
}

'Language > C' 카테고리의 다른 글

How to print out thread id from pthread_t  (0) 2012.04.06
Programmiersprache C/C++  (0) 2012.03.16
fork, wait, waitpid, zombie(좀비)  (0) 2012.03.15
strerror  (0) 2012.03.14
bsearch() 함수 설명 및 알고리즘  (0) 2012.03.09
:

fork, wait, waitpid, zombie(좀비)

Language/C 2012. 3. 15. 15:51

fork()함수


프로그램내 동작하고 있는 프로세스를 복사하고 복사한 프로세스를 독립적으로 돌려주는 함수입니다 흔히 원복 프로세서를 부모프로세스라 부르고 복사한 프로세스를 자식프로세스라 부릅니다
.

 

헤더    unistd.h

형태    pid_t fork(void); 

반환    pid_t 실행에 실패하면 -1 을 반환부모에게는 새로 생성된 자식 프로세스 PID가 반환되며자식 프로세스에는 0이 반환됩니다.

 

#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int global_var = 0;

int main()
{
  pid_t ret_pid, child;
  int local_var = 0;

  ret_pid = fork();
  if(ret_pid < 0)
  {
    printf("fork() error\n");
    return -100;
  }
  else if(ret_pid == 0)
  {
    global_var++;
    local_var++;
    printf("CHILD - my PID : %d parents PID : %d \n", getpid(),getppid());
  }
  else
  {
    sleep(10);

    global_var += 5;
    local_var += 5;
    printf("PARENT - my pid : %d chail's PID : %d\n", getpid(),ret_pid);
  }
  printf("\t global_var : %d \n",global_var);
  printf("\t local_var : %d \n",local_var);
  return 0;
}


 

결과>>


 

좀비 프로세스

-  프로세스 종료 후 메모리상에서 사라지지 않은 프로세스

 

좀비 프로세스 생성 이유

-  자식  프로세스가  종료하면서  반환된    0  커널이  부모  프로세스에  전달한    자식

프로세스를 소멸시킴.  

-  반환값을 부모 프로세스에 전달하지 못한 경우 자식 프로세스는 좀비로 존재.

-  부모 프로세스가 커널에게 종료된 자식 프로세스의 리턴값을 전달 요청을 해야만  

커널이 리턴값 전달 가능함

 

종료된 자식 프로세스의 리턴값 요청 함수 
 
1. wait 함수 
 
#include <sys/types.h> 
#include <sys/wait.h> 
 
pid_t wait(int * status); 
성공시 종료된 자식 프로세스  ID, 실패시  -1 리턴 
 
-  status : 포인터  status가 가리키는 변수에 자식 프로세스 종료시 리턴하거나   
exit 함수 호출시 전달한 인자값이 저장됨 
-  매크로함수 WEXITSTATUS(status)로 종료시 리턴값이나  exit() 인자로 넘겨진 값 확인 
-  호출 시점에 종료된 자식 프로세스가 없으면  blocking 상태에 빠짐
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int global_var = 0;

int main()
{
  pid_t ret_pid, child;
  int local_var = 0;
  int state;

  ret_pid = fork();
  if(ret_pid < 0)
  {
    printf("fork() error\n");
    return -100;
  }
  else if(ret_pid == 0)
  {
    global_var++;
    local_var++;
    printf("CHILD - my PID : %d parents PID : %d \n", getpid(),getppid());
  }
  else
  {
    global_var += 5;
    local_var += 5;
    printf("PARENT - my pid : %d chail's PID : %d\n", getpid(),ret_pid);
    
    child = wait(&state);
    printf("\t Child PID = %d \n", child);
    printf("\t return value = %d \n", WEXITSTATUS(state));
  
    sleep(10);
  }

  printf("\t global_var : %d \n",global_var);
  printf("\t local_var : %d \n",local_var);
  
  return 0;
}


 

결과>>


 

 2. waitpid 함수  (wait함수의  blocking 상태 해결)

 

#include <sys/types.h>

#include <sys/wait.h>

 

pid_t waitpid(pid_t pid, int * status, int options);

성공시 종료된 자식 프로세스ID(경우에 따라 0), 실패시  -1 리턴

 

-  pid :   종료 확인을 원하는 자식 프로세스  ID. 임의의 자식 프로세스인 경우  -1 대입.

-  status :  wait 함수의  status와 같은 역할

-  options :  sys/wait.h에 정의된  WNOHANG’ 상수를 인자로 전달하게 되면 이미 종료한

          자식 프로세스가 없는 경우 blocking 상태로 가지않고 바로 리턴함.

       이때 waitpid 함수의 리턴값은  0이 된다.

  

#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int global_var = 0;

int main()
{
  pid_t fork_ret, child;
  int local_var = 0;
  int state;

  fork_ret = fork();
  if(fork_ret < 0)
  {
    printf("fork() error\n");
    exit(1);
  }
  else if(fork_ret == 0)
  {
    global_var++;
    local_var++;
    printf(" CHILD - my PID : %d parent's PID : %d \n", getpid(),getppid());
    sleep(10);
  }
  else
  {
    global_var += 5;
    local_var += 5;
    printf("PARENT - my PID : %d child's PID : %d \n", getpid(),fork_ret);

    do
    {
      sleep(3);
      puts("3초 대기");

      child = waitpid(-1&state, WNOHANG);
    }
    while(child == 0);

    printf("\t 종료된 자식 프로세스 ID = %d \n", child);
    printf("\t 종료된 자식 프로세스의 리터 값 = %d \n", WEXITSTATUS(state));
  }
  printf("\t global_var : %d \n", global_var);
  printf("\t local_var : %d \n", local_var);
  
  return 0;

}


 

 결과>>

 

waitpid 함수의 호출 시점은??

-  자식 프로세스가 종료되는 순간 부모 프로세스가 waitpid 함수를 호출하도록 해야함

-  자식 프로세스가 종료된 시점에 발생하는 시그널  SIGCHLD를 이용

-  sigaction 함수를 사용하여  SIGCHLD가 발생시 부모 프로세스가 자식 프로세스의 리턴

값을 읽도록 함

 


좀비 프로세스확인 

 

 결과>> wait함수 실행시 ps -u를 입력하여 확인합니다


STAT의 Z가 zombie를 뜻합니다


STAT에 Z가 없는 것을 확인 할 수 있습니다



시그널(SIGCHLD)의 이용

SIGCHLD : (시그널무시)자식프로세서 종료

sigemptyset() 주어진 마스크 셋의 모든 필드를 설정하거나 헤제한다

#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

void z_handler();

int global_var = 0;

int main()
{
  pid_t fork_ret, child;
  int local_var = 0;
  int state;

  struct sigaction act;
  act.sa_handler = z_handler;
  sigemptyset(&act.sa_mask);
  act.sa_flags =0;

  state = sigaction(SIGCHLD, &act,0);
  if(state != 0)
  {
    puts("sigaction() error\n");
    exit(1);
  }
  
  fork_ret = fork();

  if(fork_ret < 0)
  {
    printf("fork() error\n");
    exit(1);
  }
  else if(fork_ret == 0)
  {
    global_var++;
    local_var++;
    printf(" CHILD - my PID : %d parent's PID : %d \n", getpid(),getppid());
  }
  else
  {
    global_var += 5;
    local_var += 5;
    printf("PARENT - my PID : %d child's PID : %d \n", getpid(),fork_ret);
    
    sleep(5);
  }
  

  printf("\t global_var : %d \n", global_var);
  printf("\t local_var : %d \n", local_var);
  
  return 0;

}

void z_handler()
{
  pid_t child;
  int state;
  
  child = waitpid(-1&state, WNOHANG);

  printf("\t 소멸된 자식 프로세스 ID = %d \n", child);
  printf("\t 소멸된 자식 프로세스의 리턴 값 = %d \n", WEXITSTATUS(state));
}

 

결과>>

 
**정상적으로 자식프로세스가 종료된것을 확인 할 수있습니다

'Language > C' 카테고리의 다른 글

Programmiersprache C/C++  (0) 2012.03.16
getprocs64() (get process information on aix)  (0) 2012.03.16
strerror  (0) 2012.03.14
bsearch() 함수 설명 및 알고리즘  (0) 2012.03.09
semget() 세마포어 생성 및 접근  (0) 2012.02.02
:

strerror

Language/C 2012. 3. 14. 19:50
strerror
#include <string.h> // C++ 에서는 <cstring>

char * strerror ( int errnum );

오류 메세지 문자열을 가리키는 포인터를 얻어온다. 
errnum 의 값을 통해 발생하였던 오류에 알맞은 오류 메세지를 가리키는 포인터를 리턴한다. 이 때 리턴되는 포인터는 문자열 리터럴을 가리키고 있기 때문에 그 내용이 바뀔 수 없다. 참고로 strerror 에 의해 출력되는 오류 메세지는 현재 사용중인 컴파일러나 플랫폼에 따라 다를 수 있다.

   인자  
 

errnum

오류 번호

   리턴값
 

오류 번호에 해당하는 오류 문자열을 가리키는 포인터

   놀라운 사실 
 

이 함수는 C 표준 함수 중에서 이름에 r 이 가장 많이 포함되어 있는 함수 이다. 무려 r 이 4 개나 있다. 


   실행 예제
 

/* 

존재하지 않는 파일 unexist.ent 를 열라고 해 오류가 발생한다.
이 예제는
http://www.cplusplus.com/reference/clibrary/cstring/strerror/
에서 가져왔습니다.

 */
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main ()
{
    FILE * pFile;
    pFile = fopen ("unexist.ent","r");
    if (pFile == NULL)
        printf ("Error opening file unexist.ent: %s\n",strerror(errno));
    return 0;
}
:

bsearch() 함수 설명 및 알고리즘

Language/C 2012. 3. 9. 22:13

#include <stdlib.h>

void *bsearch( const void *key,

               const void *base,

               size_t nmemb,

               size_t size,

               int (*compar)(const void *, const void *));

 

Parameters :

key    : 찾고자 하는 키 값(Target)

base   : 찾을 대상이 있는 Array Object의 주소

nmemb  : array element 개수

size   : array element 하나의 byte size

compar : 비교함수. 각각 두 개의 파라미터는 key와 하나의 array element를 가리키는 주소값이다.

         자세한 내용은 Description 참조.

 

Return Value :

함수 실행 결과, 매칭하는 Array Object의 주소값을 리턴한다.

매칭되는 결과값이 없는 경우는 NULL을 리턴한다.

 

Description :

bsearch()함수는 binary search를 수행한다.

물론 직접 binary search 알고리즘을 구현할 수도 있겠지만 구태여 그렇게 힘들일 필요 없다.

다 만들어서 제공해주고 있으니 만들어준 사람 성의를 생각해서 그냥 잘 가져다 쓰면 된다!

 

※ 비교함수(compar)

   key 파라미터와 array element를 비교하여 key 값이 더 작으면 음수, 같으면 0, 더 크면 양수를 리턴한다.

   실제 프로그래밍시 비교함수는 직접 코딩해줘야한다.

   <비교함수 코딩 예>

   static int compare(const void *key, const void *data) {
     return *(int *)key - *(int *)data;
   }

   위의 비교함수를 이용하여 bsearch()함수를 호출할 때는 이렇게 하면 된다.

   int *d = (int *d)bsearch(&key, data, sizeof data / sizeof(int), sizeof(int), compare);

 

bsearch 알고리즘:

 

lsearch()나 lfind()가 테이블의 첫번째 요소부터 마직막 요소까지 하나씩 데이터를 검색한다면 bsearch()는 이진 검색으로 매우 빠르게 자료를 검색할 수 있습니다.

그러나 이진 검색을 하기 위해서는 반드시 테이블의 자료는 정령되어 있어야 합니다. 왜 이진 검생르 위해 테이블이 정렬되어 있어야 하는지 이유를 보겠습니다.

지금 테이블에 1에서 10까지 데이터가 차례로 정렬되어 있습니다.

1 21 32 43 54 65 76 87 98 190

이 테이블에서 98을 찾아 보겠습니다. 우선 전체 테입블 요소 중 가운데에 해당하는 다섯번째 데이터와 비교합니다.

1 21 32 43 54 65 76 87 98 190

가운데 요소와 비교했더닌 검색하려는 데이터 98보다 작습니다. 그러므로 1부터 43까지는 검색할 필요가 없습니다.

이번에는 5 번째 요소와 10번째 요소의 가운데 요소인 8번째 요소와 비교합니다.

1 21 32 43 54 65 76 87 98 190

역시 찾으려는 98보다 작습니다. 이번에는 8 번째와 10 번째의 가운데에 해당하는 9 번째와 비교하게 됩니다.

1 21 32 43 54 65 76 87 98 190

lsearch()와 lfind()는 첫번째 요소부터 차례로 검색하기 때문에 9번이나 비교해야 하지만 bsearch 는 이와 같이 정렬된 자료에서 이분화해서 검색하므로 단 3번의 비교로 자료를 검색할 수 있습니다.

그러므로 매우 많은 자료에서는 이진 검색인 bsearch()가 매우 빠르게 검색할 수 있습니다.

 

'Language > C' 카테고리의 다른 글

fork, wait, waitpid, zombie(좀비)  (0) 2012.03.15
strerror  (0) 2012.03.14
semget() 세마포어 생성 및 접근  (0) 2012.02.02
inet_ntoa 64bit 사용시 에러 대처방법  (0) 2012.02.02
FILE, fopen, fprintf, fflush, fclose  (0) 2012.01.30
:

semget() 세마포어 생성 및 접근

Language/C 2012. 2. 2. 14:00

설명

semget() 함수는 세마포어 집합을 생성하거난 이미 생성된 세마포어에 접근하기 위해 사용합니다.

세마포어는 공유 자원을 동시에 여러 프로세스가 사용하는 것을 막고, 오직 자원을 하나의 프로세스만 사용할 수 있도록 보장해 주는 방법입니다. 즉, 여러 프로세스 중 공유 자원을 자신이 사용할 수 있는지 있다면 작업이 끝나기 전까지 다른 프로세스가 공유 자원을 사용할 수 없도록 다른 프로세스의 접근을 제어하는 방법을 세마포어를 이용하여 구현할 수 있습니다.

세마포어를 제일 간단히 설명한다면 특정 변수를 두고, 이 변수를 미리 확인합니다. 특정 변수를 확인하는 함수를 p()라고 하겠습니다.

  1. 프로세스는 공유자원을 사용하기 전에 p()함수를 호출합니다.
  2. p()는 특정 변수 값을 확인하여 공유 자원이 다른 프로세스가 사용 중인지의 여부를 판단하고, 다른 프로세스가 사용 중이면 그 프로세스가 사용을 중지할 때까지 대기합니다. 공유 자원이 사용 가능하다면 특정 변수값을 변경하고 복귀합니다.
  3. 프로세스는 공유 자원을 사용합니다.
  4. 프로세스는 공유 자원에 대한 작업을 완료했다면 s() 함수를 호출하여 특정 변수값을 원래의 값으로 복원합니다.

이렇게 프로세스가 s() 함수를 호출하여 변수값을 원래 값으로 변경하면 다른 프로세스의 p()함수는 공유 자원의 사용이 가능하다고 판단하게 됩니다.

 

헤더 sys/types.h
sys/ipc.h
sys/sem.h
형태 int semget ( key_t key, int nsems, int semflg )
인수
key_t key 시스템에서 세머포어를 식별하는 집합 번호
int nsems 세마포어 집합 내의 세마포어 개수로 접급 제한하려는 자원의 개수
int semflg 동작 옵션
semflg 옵션 내용
IPC_CREATE key에 해당하는 공유 세머포어가 없다면 새로 생성한다. 만약있다면 무시하며 생성을 위해 접근 권한을 지정해 주어야 한다.
IPC_EXCL 세머포어가 이미 있다면 실패로 반환하며 세머포어에 접근하지 못한다. 이 옵션이 없어야 기존 세마포어를 사용할 수 있다.
반환
-1 실패
-1 이외 새로 만들어진 세마포어 식별자 또는 key 와 일치하는 세마포어 식별자

예제

아래의 예제에서는 두개의 쓰레드를 만들어 하나의 자원인 카운터 cnt 를 서로 방해하지 않고 사용하는 모습을 보여 주고 있습니다.

#include<pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int          cnt   = 0;
static int  semid;

void p()
{
   struct sembuf pbuf;

   pbuf.sem_num   = 0;
   pbuf.sem_op    = -1;
   pbuf.sem_flg   = SEM_UNDO;

   if ( -1 == semop(semid, &pbuf, 1))
      printf( "p()-semop() 실행 오류\n");
}

void v()
{
   struct sembuf vbuf;

   vbuf.sem_num   = 0;
   vbuf.sem_op    = 1;
   vbuf.sem_flg   = SEM_UNDO;

   if ( -1 == semop( semid, &vbuf, 1))
      printf( "v()-semop() 실행 오류\n");
}

void *fun_thread1(void *arg)
{
   while( cnt < 5)
   {
      p();
      printf( "thread1 실행\n");
      cnt++;
      usleep( 100);
      printf( "thread1 종료\n");
      v();
   }
   return NULL;
}

void *fun_thread2(void *arg)
{
   while( cnt < 5)
   {
      p();
      printf( "thread2 실행\n");
      printf( "카운터= %d\n", cnt);
      usleep( 100);
      printf( "thread2 종료\n");
      v();
   }
   return NULL;
}

int main(int argc, char *argv[])
{
   pthread_t thread1;
   pthread_t thread2;
   union semun{
      int                  val;
      struct   semid_ds   *buf;
      unsigned short int  *arrary;
   }  arg;

   if ( -1 == (semid = semget( IPC_PRIVATE, 1, IPC_CREAT ¦ 0666)))
   {
      printf( "semget() 실행 오류\n");
      return -1;
   }

   arg.val  =  1;                // 세마포어 값을 1로 설정
   if ( -1 == semctl(semid, 0, SETVAL, arg))
   {
      printf( "semctl()-SETVAL 실행 오류\n");
      return -1;
   }

   pthread_create(&thread1, NULL, fun_thread1, NULL);
   pthread_create(&thread2, NULL, fun_thread2, NULL);
   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL);

   if ( -1 == semctl(semid, 0, IPC_RMID, arg))
   {
      printf( "semctl()-IPC_RMID 실행 오류\n");
      return -1;
   }
   printf( "프로그램 종료\n");
   return 0;
}
]$ ./a.out
a
]$

'Language > C' 카테고리의 다른 글

strerror  (0) 2012.03.14
bsearch() 함수 설명 및 알고리즘  (0) 2012.03.09
inet_ntoa 64bit 사용시 에러 대처방법  (0) 2012.02.02
FILE, fopen, fprintf, fflush, fclose  (0) 2012.01.30
multicast(receive)  (0) 2012.01.16
:

inet_ntoa 64bit 사용시 에러 대처방법

Language/C 2012. 2. 2. 12:43
32비트에 컴파일할 때 문제가 없던 일들이..

64비트에서 일어난 경우 중 하나입니다.

inet_ntoa() 이 함수

컴파일 에러는 없지만.. 이 함수가 실행하는 시점에서 Segment fault 라는 메시지를 접하실겁니다.


해결방법은..

간단히 헤더에 한줄만 추가해주면됩니다.

#include <arpa/inet.h>


그리고 기존에 아래와 같이 코딩하고 계셨다면..

printf("%s ", inet_ntoa(ip->saddr));


아래와 같은 에러를 접하셨을겁니다.

error: incompatible type for argument 1 of ‘inet_ntoa’


간단히 해석해보면 inet_ntoa() 함수의 인자값이 잘못된다는 얘기입니다

아래와 같이 수정하시면 해결이 됩니다.

printf("%s ", inet_ntoa(*(struct in_addr *)&ip->saddr));

'Language > C' 카테고리의 다른 글

bsearch() 함수 설명 및 알고리즘  (0) 2012.03.09
semget() 세마포어 생성 및 접근  (0) 2012.02.02
FILE, fopen, fprintf, fflush, fclose  (0) 2012.01.30
multicast(receive)  (0) 2012.01.16
multicast(send)  (0) 2012.01.16
:

FILE, fopen, fprintf, fflush, fclose

Language/C 2012. 1. 30. 17:04

char  fname[32]="/log/test.log";
FILE  *debug;
debug = fopen(fname, "a+");
fprintf(debug, "%s\n","test");
fflush(debug);
fclose(debug);

'Language > C' 카테고리의 다른 글

semget() 세마포어 생성 및 접근  (0) 2012.02.02
inet_ntoa 64bit 사용시 에러 대처방법  (0) 2012.02.02
multicast(receive)  (0) 2012.01.16
multicast(send)  (0) 2012.01.16
포인터, 배열, 구조체 연산  (0) 2012.01.11
: