728x90

실습 코드에

close(1); <<요런 라인이 있었다..

 

1이 뭐여?

 

알고보니 unistd.h 에서 사용하는 파일디스크립터(file descriptor)의 매크로이당.. ( POSIX API의 일부란다)

 

매크로란 인수형 등의 인자를 쉽게 기억하기(?) 위해

또는 코드 가독성을 올리기위해 사용하는 것...

아래 표의 첫번째칸 값을 넣으나

세번째칸 값을 넣으나 똑같다는 것이다

보통 C에서 대문자로 표현된당..

 

 

고로 close(1) 은

스탠다드 아웃풋 디스크립터를 닫는다 즉, 더이상 본 프로세스에서 표준 출력을 쓰지 않겠다 라는 것이다.

close(0) 은 표준입력을 받지 않겠다는 것이다.

위 세개의 파일 디스크립터, 스트림은 open을 따로 하지 않아도 프로세스 생성 시 자동으로 생성된다.

 

자동으로 생성되는 것에 대한 내용은 여기에 썼었다.. 물론 구글에 더 좋은 글이 많을 것이당

 

2021.10.30 - [프로그래밍 공부/OS] - [Linux] 표준 입력, 표준 출력, 표준 에러 출력, 파일디스크립터

 

[Linux] 표준 입력, 표준 출력, 표준 에러 출력, 파일디스크립터

리눅스 공부하면서... 이해한걸 또 까먹을까봐 내식대로 적어두려함 출처는 학교 리눅스 수업 + 모두를 위한 리눅스 프로그래밍(아오키 미네로, 2018) 이다. 컴퓨터는 기본적으로 1차원 바이너리

holsui.tistory.com

 

 

나는 close(1) 이녀석 행색이 맘에안들어서

close(STDOUT_FILENO) 으로 변경하였따....

 

 

참고자료 : 오늘 날 도와준 위키피디아 땡큐!

 

728x90
728x90

*Ubuntu 20.04 에서 컴파일했습니당..

 

 

빌드시 아래 메시지가 뜬다면....

pthread library 가 제대로 링크 되지 않은것이다...

 

undefined reference to 'pthread_cancel'

undefined reference to `pthread_create'

undefined reference to `pthread_join'

 

이거 배워놓고 자꾸 잊어먹는다...

 

pthread.h 를 포함하고 pthread 관련 함수 사용시

compile 시 -lpthread 옵션을 꼭 넣어주어야한다!

 

make file 작성시에는

CC = gcc
CFLAGS =
LDFLAGS = -lpthread


[target] : [prerequisites(.o file 등)]

        $(CC) -o $@ $< $(LDFLAGS)

 

요렇게 작성하면 되고

 

직접 컴파일할때는

 

gcc -o [target] [소스코드] -lpthread

 

이렇게 옵션 넣어주면 된다...

 

그러나 lpthread 말고 pthread 옵션을 넣어도 되는데

둘의 차이는

lpthread 는 pthread 라이브러리와 링크만 해주고

pthread 는 라이브러리 링크+매크로 사용이 가능하다.

그래서 pthread 사용을 추천하는 글이 많다...

그러나 pthread 옵션은 운영체제에 따라 동작하지 않을 수 있다... 아마 그래서 내 실습자료도 lpthread 옵션을 사용한듯허당!

 

 

출처 :

728x90
728x90
더보기

「Linux, system call, operating system, asynchronus programming, 비동기 프로그래밍


오늘은 학교 과제하다가 잘 복습해두고픈 내용이 있어서 써본다

Linux system programming 수업에서 요즘 Signal 부분 과제를 하고있다...

오늘 실습한 코드는signal(알람수신자) 과 alarm(알람발신자) 을 사용해서 동기적 프로그래밍하기!

나를 혼란스럽게 했던 내용...
* signal 은 signal 보내는게 아니라 받는 함수다 ㅡㅡ .... 진짜 넘하지않냐....
* 뭐..안넣어도 세상이 워낙 좋아 컴파일이 되긴했지만 alarm 사용을 위해 unistd.h 헤더 포함시켜주기...
*signal인터페이스

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

첫번째 인자 signum 은 MACRO를 사용한다 ( SIGINT, SIGBUS,SIGALRM,SIGTERM 등...)
(man signal 참고*)
두번째 인자는 함수 포인터이다... 위 형식에 맞게 함수를 선언하고 넣어주면 된다.

첫번째 인자에 해당하는 signal 을 받으면 두번째 인자의 함수가 실행된다.
default 동작도 있다(무시, 종료 등..)


흐름은....
1. alram signal 을 받았을 때(alarm 함수를 통해 'SIGALRM' 시그널 보냄) 어떤 동작을 수행할지 변경하기위해
SigAlarmHandler 함수를 만든다.(이 함수가 signal 의 두번째 인자, 함수 포인터로 들어간다)
SigAlarmHandler :
여기에는 점을 하나 찍어주는 코드와
signal을 다시 호출하는 코드가 들어간다.
( 여기에서 또 두번째 인자로 핸들러를 재귀적으로 넣어주는데, 일부 운영체제에서 핸들러는 한 번 수행된 뒤 초기화되기 때문이다...)

2. 최초로 signal 을보낼 setPeriodicAlarm 함수를 선언해준다.
signal함수로 SIGALRM 받았을 시의 Handler를 설정해주고
alarm() 호출! 파라미터는 시간이 들어간다 (unsigned int, 초단위.. )
0이면 pending 중인 모든 알람이 취소된다

3. main 에서 setPeriodic Alarm 을 호출한다...

그러면 다른 동작이 모두 종료될때까지 반복해서 alarm handler 에 등록한 내용이 주기적으로 수행된다.

실습코드

#include <stdlib.h> #include <stdio.h> #include <signal.h> #include <unistd.h> static unsigned int AlarmSecs; // 함수 종료시에도 값 유지되는 전역변수 // static : 다른 파일 접근을 막기 위함 // void SigAlarmHandler(int signo) { // 한 번 호출 후 Hanlder 사라지는 OS가 있으므로 // 재귀적으로 재등록 if( signal(SIGALRM, SigAlarmHandler) == SIG_ERR) { perror("signal"); exit(1); } // 다시 알람 시스템 콜 요청 // 전역변수 사용(함수가 사라지므로) alarm(AlarmSecs); /* DO something */ // 버퍼캐시 바로 flush printf("."); fflush(stdout); return; } int SetPeriodicAlarm(unsigned int nsecs) { if( signal(SIGALRM, SigAlarmHandler) == SIG_ERR) { return -1; } // 정상종료 시 -1 return AlarmSecs = nsecs; alarm(nsecs); return 0; } int main() { int i,j; printf("Doing something every one sec.\n"); // 1초마다 정해진 동작 하는 함수(asynchronus) SetPeriodicAlarm(1); //위 알람과 상관없이 자기 일 하는 코드.. // asynchronuos 함을 더 직접적으로 보기 위해 내맘대로 넣어본 yum! for(i = 0;i < 1000000;i++){ if( i%100000 == 0) printf("\nyum!\n"); for(j = 0; j<20000; j++) {} } return 0; } 67,1 Bot


어마어마한루프는... 일부러 시간끌기용으로 넣어보았다 숫자는 별의미없음

수행결과는 이렇게 나왔당


끝!

참고한것 :학교수업자료, 아오키미네로 「모두를위한 리눅스 프로그래밍」, man alarm

728x90
728x90


요며칠 바람이 엄청불더니 낙엽이 쌓여서 미끄러운 등산길

이제 넘 추워서 등산다닐날이 많이 남지 않은 것 같당


등산끝나고 미나리삼겹살먹었다 존맛...



728x90
728x90

학교과제중에 진짜 미쳐버릴거같았던 에러.... 오만곳을 다뒤졌는데 시원한해결책을 못찾고 3시간 허비...

애먼 컴파일러가 잘못된줄알구....버전 바꿧다가막...난리침

 

결론부터 말하자면 컴파일러가 아니라 함수 파라미터가 잘못된것이었음!!!

 

나는 아래 함수에서  strtok 함수를 쓰며 에러가 났는데, strcpy 도 파라미터를 잘못넣으면 비슷한 에러메시지가 난다...

캐릭터배열 너무 다루기 힘들다 흑흑흑

좀 투박하고..더좋은 방법이있을거같지만 일단 돌아가니 제출하고 자야지 ㅠ

 

아래 코드는 실제 과제내용은 당연아니고 오류나는 부분만 실험해보려고 이래저래 돌려본 코드...

 

오류나는 코드

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

//오류나는경우

int splitstr(char* cmd) {
    char *ptr =strtok(cmd, " ");
    while (ptr != '\0')
    {
        printf("%s\n", ptr);
        ptr = strcpy('\0', " ");
    }
    
}

int main(int argc, char const *argv[])
{
    splitstr("hello hi hi");
    return 0;
}

 

고친 코드(2줄 추가됨)

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


int splitstr(char* cmd) {
    char str1[100];					//char 배열 선언하고
    strcpy(str1, cmd);					//복사..
    char *ptr =strtok(str1, " ");
    while (ptr != '\0')
    {
        printf("%s\n", ptr);
        ptr = strtok(NULL, " ");
    }
    
}

int main(int argc, char const *argv[])
{
    splitstr("hello hi hi");
    return 0;
}

   

 

728x90
728x90

리눅스 공부하면서... 이해한걸 또 까먹을까봐 내식대로 적어두려함

 

출처는 학교 리눅스 수업 + 모두를 위한 리눅스 프로그래밍(아오키 미네로, 2018) 이다.

 

컴퓨터는 기본적으로 1차원 바이너리를 읽는다.

따라서 모든 데이터는 1차원으로 바뀌어서 흐른다... 이것을 스트림이라고 할 수 있다.

 

프로세스가 하나 생성되면 해당 프로세스에 3개의 스트림이 자동으로 생성되는데,

이것이 표준입력, 표준출력, 표준에러출력이다.

이들은 각각 0,1,2 의 디스크립터(ID같은것?)를 갖는다. 그치만 그걸 유저에게 외우라고 하진않고....!

STDIN_FILENO, STDOUT_FILENO , STDERR_FILENO 라고 매크로를 지정하여뒀으니 이걸 넣어서 인자로 주고받을수있다

 

이것은 컴퓨터의 중요한 개념인 추상화(abstraction)를 내포하고있는데

내 프로세스는 이 표준입력이 파일에서 온건지 키보드로 친건지는 신경쓰지 않고 똑같이 처리할 수 있다.

표준 출력을 내보낼 때도 마찬가지다. 이걸 모니터에 쓰든 다른 프로세스로 전달하든 알바가 아닌것이당......

 

암튼 이 스트림들을 우리는 수많은 입출력이 포함 된 API 를 통해 간접적으로 쓰고있지만

시스템콜로 직접 호출하려면

unistd.h 헤더를 포함하고, read, write를 사용하면 된다.

write 를 쓰려면

문자열(char []) buf 를 선언하고(당연 변수명은 달라도 됨)

write(STDOUT_FILENO, buf, sizedof(Buf)-1);

 

위와같이 하면 된다.

 

buf는 우리가 흔히 '버퍼링 걸린다' 고 할때의 버퍼인데 (이말도 안쓴지 10년넘긴한듯...) 암튼....

저렇게 하면 buf 에 들어있는 문자열이 표준출력으로 나온다! ( 터미널에 찍힘 ) 파이프로 연결해서 다른데로 보낼수도있다..

 

 

해당내용은 위에 언급한 책 64~71 페이지를 읽어보면 더 자세하고 정확하게 나온당......끗!

728x90
728x90

우리집에온지 3일째....
정말 작은친구...
저 화분도벌레 모종키우는 그 비닐화뷴보다도 작은 미니화분인데
나의 제제는(글쓰면서 이름지었다...벌제 라고 하려다가 그건좀 그래서...) 더 작다......

얘가 커서 벌레를 잡아먹는다니 참 말도안되는 세상이다

제제를 준 친구가 지난 초여름에 바질도 한 화분 줬었는데
내가 미국간 사이 어머니께서 너무 심적으로 육체적으로 바쁘신바람에 죽어버렸당.....
수경재배중인 야자트리오만 살아남았따.....
난 원래 식물관련 전공인데 하는일이라곤 식물들 죽이는것뿐......

엄마가 얘는 죽이지말고 잘키워보자했따...

나눠준 친구는
수태에 키우면 잘큰다고하고... 너무 직접 잎에말고 주변부로 수태가 마를때마다 물을 주라고 했다
글고 수태밑에는 안썩게 물 잘빠지는거 하래서 난석이랑 하이드로볼 깔았음

잘키워서 꽃도보고 주변에 나눠주고싶당 잘 자리잡아주길

오늘 아침에 물주는데 넘 작고 소중해서 행복했따



728x90
728x90

쓰르라민지 귀뚜라민지 암튼 가을벌레가 우는 계절이다
걔네들 머릿수를 세며 올라가다가
또 딴생각해서 까먹다가
넌 쟤랑 목소리가 다르구나 뭐 이런생각을 하며 올라왔다

근데 매미도 같이울고있다 이 미친세상!

암튼 지금은 정상에 앉아 쉬며 글을쓰는중....
이거 해보니까 등산도 귀찬은데 내려가서 후기 쓰려니 잘 안써져서ㅎㅎ...

올라오면서 비스코뭐시기 커피과자를 먹었다
먹을때를 놓쳐 눅눅해졌지만 뭐어떤가....
과자를먹고 어짜피 땀에절어 빨아야할 티셔츠에 슥슥 손을닦았다
나는 이상한 생각들이 맘대로 머릿속을 스쳐지나가게 놔두고
가끔 이상한 생각을 입으로 뱉어도 보고
또 정체모를 가을벌레를 허술하게 세면서 산을 올라왔다

좋군 흠흠



728x90

' > 일상' 카테고리의 다른 글

등산등산  (2) 2021.11.10
새식구 벌레잡이제비꽃  (0) 2021.10.16
등산기록 몰아쓰기 09/27, 09/29, 10/2, 10/4  (0) 2021.10.05
210924 아침 등산 후기  (0) 2021.09.26
abc 주스/디톡스 주스 후기  (0) 2021.09.22

+ Recent posts