김정인 강사님은 오픈소스가 중요하다며
리눅스 커널 및 딥러닝의 구현 소스를 취미 삼아 매일 분석 하는 오픈 소스 매니아 입니다.
소스를 통해 이해 한다며 무작정 소스 분석으로 모든 원리를 이해하려 하므로
수강 시 소스 폭탄에 주의 해야 합니다.
강의문의 : jikim@imguru.co.kr
講義
受講レビュー
- Linuxシステムプログラミング
- Linuxシステムプログラミング
投稿
Q&A
signal함수와 관련하여 질문있습니다.
안녕하세요! 컴파일과 링킹의 동작 원리를 정확히 짚어낸 아주 훌륭한 질문입니다.결론부터 말씀드리면, C언어 링커(Linker)는 함수를 연결할 때 오직 '함수 이름'만 확인할 뿐, 반환 타입이나 매개변수 정보는 전혀 검사하지 않기 때문입니다.심볼 테이블에는 '함수 이름'만 기록됩니다.C언어는 컴파일을 마친 목적 파일(.o)에 반환 타입 정보 없이 함수 이름(signal)만 심볼로 남깁니다. 따라서 링커는 표준 라이브러리(libc)에서 이름이 같은 signal 함수를 찾아 아무 에러 없이 연결해 줍니다.실행 시 반환값은 레지스터에서 자연스럽게 무시됩니다.실제 signal 함수는 실행 후 반환값(이전 핸들러 주소)을 CPU 레지스터(RAX)에 담아 돌려줍니다. 하지만 main 함수에서는 반환 타입을 void로 알고 있어 그 레지스터 값을 읽지 않고 무시한 채 다음 줄로 넘어가므로 충돌 없이 정상 작동합니다.강의에서는 원래의 복잡한 원형(void (*signal(int, void (*)(int)))(int);) 대신, '두 번째 인자로 함수 포인터를 넘긴다'는 핵심에 집중하기 위해 반환 타입을 void로 단순화하여 보여드린 것입니다. (단, 를 #include 하면 원형이 충돌해 컴파일 에러가 발생합니다.)더 궁금한 점이 있다면 언제든 질문해 주세요!
- いいね数
- 0
- コメント数
- 1
- 閲覧数
- 26
Q&A
함수 메뉴얼을 보기 위한 단축키
안녕하세요. fopen은 라이브러리이므로 섹션 번호 2번 입니다. 2를 눌렀다가 shifk+k를 누르면 됩니다.
- いいね数
- 0
- コメント数
- 1
- 閲覧数
- 149
Q&A
17분 2초에
안녕하세요.말씀하신 대로 설명이 애매 한게 있네요.hello, world #1만 출력되는 이유는 \n가 없어서가 아니라 msg1, msg2, msg3 까지는 버퍼에 읽었지만 printf가 hello, world#1\0 까자만 첫번째 문장으로 해석해서 출력했기 때문이 맞습니다.printf("%s\n", inbuf) 문에서 \n가 없었으면 전체가 안찍혀야 맞는데 \n가 있어서 첫번째 문장만 한문장으로 인식하여 출력된 것입니다.좋은 지적 감사합니다.
- いいね数
- 0
- コメント数
- 1
- 閲覧数
- 129
Q&A
혹시 고급과정의 경우 하반기 몆월쯤 나올까요?
안녕하세요.리눅스 시스템 프로그램 고급 과정은 준비 중이며 출시는 11월~12월 사이에 될 것 같습니다. 감사합니다.
- いいね数
- 0
- コメント数
- 2
- 閲覧数
- 184
Q&A
fputs에서 fwrite 로 변경 후 버퍼타입이 헷갈리는데요
안녕하세요.fputs는 문자열에 '\n'가 나오면 버퍼가 비위지는 fflush가 되기 때문에 출력 되고 fwrite는 라이브러리 버퍼가 꽉 채워지지 않으면 출력이 안되므로 fully 버퍼 방식을 사용 합니다. 똑같이 stdout 으로 출력 되더라도 버퍼링을 안 할 수도 있고 , line buffered, fully buffered 로 작동되도록 library 안에 구현 되어 있습니다.
- いいね数
- 0
- コメント数
- 1
- 閲覧数
- 178
Q&A
혹시 고급과정도 출시가 되는지요?
안녕하세요.시스템 프로그램 고급과정은 2025년 하반기 출시 예정 입니다. 감사합니다.
- いいね数
- 0
- コメント数
- 1
- 閲覧数
- 243
Q&A
강사님 후속 강의
아직 계획하지 않고 있습니다.
- いいね数
- 0
- コメント数
- 1
- 閲覧数
- 188
Q&A
Insert_data에서 prev_tmp를 지웠을 때, 성능향을 기대할 수 있을까요?
안녕하세요.tree 의 insert_data 함수의 개선 과정을 문의 하신 것 같습니다. 해당 소스를 보면 if( root == 0 ) { root = temp; return; } while(p) { prev = p; if( p->data > data ) p=p->left; else if( p->data right; else return; } if( prev->data > data ) prev->left = temp; else prev->right = temp;위 부분이 아래와 같이 바뀐 것이므로 while(*p) { if( (*p)->data > data ) p=&(*p)->left; else if( (*p)->data right; else return; } *p = temp;while 루프 안의 prev = p 가 사라진 것과 while 아래 쪽의 if ~ else 구문이 사라진 것이 주요 합니다. while 루프 안의 코드 삭제는 log N 번 이라 하더라도 데이터가 많은 경우 성능 향상을 기대할 수 있습니다. 또한 While 아래쪽의 if ~ else 또한 while 안쪽은 아니지만 insert_data 함수가 여러 번 호출 되었을 때 성능상 이점이 되리라 생각 됩니다.
- いいね数
- 0
- コメント数
- 1
- 閲覧数
- 253
Q&A
tail노드의 이유 & 메모리 풀링 관련
질문 내용에 항목 별로 답변 드리겠습니다. 메모리 풀링은 그렇다면 주로 어느정도의 사이즈를 가정할 수 있을때나 시스템상 핸들링 할 수 있는 최대치를 넣어 구현한다는 말씀이신가요?그렇다면 내부적으로 너무 많은 메모리를 사용하지않고 낭비되어 효율성이 떨어지지 않나요? 어느 시점에 써야 하는지에 대한 부분이 좀 명확하지않아, 어떤 상황에 써야 되는 기법인지 묻고 싶습니다.답변 : 대부분 시스템에서는 메모리 풀링의 최대치를 관리 하고 있습니다. 예를 들어 운영체제의 프로세스의 최대수 1024, 한 프로세스에서 오픈 가능한 파일수 1024등 너무 메모리를 낭비 하지 않는 선에서 시스템에 필요한 최대수를 메모리 풀링 하면 됩니다. 2번째는 현 tail 노드를 추가하는 부분에 있어서 .... 왜 마지막 노드의 next가 NULL인것에서 문제가 생기는 지 이해가 잘 되지 않습니다.for문이나 while문으로 loop하여 display하는것으로 가정했을때 마지막 노드 next가 0이게 되면 더이상 반복문이 실행되지않고 끝나게 되면서, NULL이 프린트 되지않고 나오지않나요?답변 : 포인터 변수 temp에 NULL이 들어온 경우 그대로 역참조 하게 되면 프로세스가 런타임 상에서 죽게 됩니다. NULL은 0번지를 의미하고 0번지를 접근하면 운영체제가 해당 프로세스를 죽게 만듭니다. 예) temp->data ==> (*temp).data => (*0).data 0 번지를 참조함 예시로 for문 중간에 왜 아무것도 기입하지 않는 부분도 어떻게 컴파일은 진행이되고 세크먼트로폴트 결과가 나오는걸까요? 답변 : for문 중간은 조건문 이므로 조건이 필요하지 않은 경우 생략할 수 있습니다. 컴파일러는 이를 에러 처리 하지 않습니다. 하지만 for문의 조건을 통과하게되면 위에 답변 처럼 temp가 NULL 인 경우temp->data 문법에서 세크먼트 폴트 예외가 발생 하여 죽게 됩니다. 혹시 선생님 말씀은 null로 마지막 node가 설정되지 않은 쓰레기값이 설정되었을때를 방지하기위해 tail노드를 추가적으로 안전하게 설치하자는 말씀이실까요?답변 : tail을 사용하여 종료 조건을 판단 하면 NULL을 만나지 않게 되어 프로세스가 죽는 문제를 해결할 수 있습니다. tail의 next는 NULL로 되어 있지 않고 자신을 가리키기 때문 입니다.
- いいね数
- 0
- コメント数
- 2
- 閲覧数
- 395
Q&A
eval(repr(p)) 가 진짜 Pair 객체로 만들어지는 이유?
eval() 함수는 string을 이자로 받습니다. 이때 string "Pair(3,4)" 가 입력되면 객체를 생성합니다. repr(p)는 "Pair(3,4)"를 출력 하게 됩니다. 따라서, 해당 클래스에 repr이 재정의 되어 있으면 자신과 같은 객체를 생성할 수 있게 됩니다.
- いいね数
- 0
- コメント数
- 1
- 閲覧数
- 308








