'C'에 해당되는 글 27건

  1. 2010.07.30 외부 Thread에서 GTK 위젯 제어할시 동기화 문제 해결 5
  2. 2010.06.24 오늘도 실수.. iconv
  3. 2010.05.31 mmap 사용시 알아둘 사항 (버스오류)
  4. 2009.06.22 아아 또 실수~! 4
  5. 2009.06.22 주의력 부족 2

외부 Thread에서 GTK 위젯 제어할시 동기화 문제 해결

내가 만드는 삽질 프로그램이 하나 있는데...

얘가 원래 터미널용 프로그램이라서.. 좀 뽀대나게 겉모습을 "Music Player"같이 변모시켜보고자

Front End를 좀 만들기로 했었다.

근데 하나의 프로세스에다가

"(터미널때) 원래 실행되는 루틴 + Gui Event 콜백(Gtk 므로  gtk_main(); )을 넣다보니......

원래 진행되어야 하는 부분이 gtk_main() 때문에 수행이 되지 않으므로.......

할수 없이 pthread를 사용해서 그 두 부분을 분리하기로 했다

(난 개인적으로 스레드 정말 싫어해서... 터미널용 프로그램에서도 다행히(?)도 스레드 사용을 안했

아 하나 했었다... timer 관련해서 0.01초마다 카운터 올리는 콜백(?)함수를 사용했지...

사실 이부분도 더 신경써서 고쳐야되는데 아직도 방치중이다 아아...)

              main();
                           |
                   pthread_create();
                           |
            ------------------------------
           |                                            |
terminal_program                       create_gtk_widgets
          |                                             |
          |                                      gtk_main();
    emit gtk signal ---------------------|     
거지같아서 그림으로 대체

DIA로 열심히 그렸는데... 일헌 그림이 짤려버렸군여..

사용자 삽입 이미지

확실히 텍스트로 찍찍 그어서 만든 조합보단 훨씬 멋있다!

처음엔 신경쓰다가 결국엔 대충 그렸으니깐 "저거 이상해여" 테클걸진 말아달라는,.

코드는 기껏해야 몇천줄인데 저렇게 보니깐 엄청 뭔가 한것같이 느껴지네...ㅋ 그림의 위엄 ㅋ

처음에 분기하는 부분은 pthreaad로 내가 직접 생성한거구

Terminal Thread를 나눈건.. 내가 직접 나눈것이 아니라, Timer라이브러리에서 Thread를 나누는것.

(이 부분은 별 신경 안썼다... )

내가 원하는건 왼쪽 (MPD Event Callback이랑 Timer Callback)에서 Gtk한테

"라벨 위젯 글자좀 바꿔주셈" 이라고 요청한것...

근데 그냥 이렇게 하면.. 몇십초 동안 프로그램이 잘 동작하다가 갑자기 죽어버리거나,

갱신이 안되고 계속 멍때리고 있는 문제가 발생한다..... (

처음엔 내가 만들었던 소스코드가 문제가 있나싶어서 열심히 뒤졌지만... 그래도 안나오는거짐..

gdb로 디버깅해도 이상한데서 죽어버리거나, 프로그램은 잘 살아 있는데도 글자갱신이 안되는

문제가 그대로 발생했었다..

이게 뭔가... 분명 GUI 씌우기 전에는 제대로 동작을 했었는데.. 씌우고 나서 안되니..

음.... 그러다가 갑자기 thread에 feel이 와서 구글을 찾아보니 왠걸..

http://library.gnome.org/devel/gdk/stable/gdk-Threads.html

역시 매뉴얼을 잘 읽어봐야 한다 -_-.......................

Gtk랑 pthread랑 같이 사용한다면..

gdk_threads_enter();

GTK_SourceCode;

gdk_threads_leave();

왜 같이 사용해야한다...

즉 다른 thread에서 GTK 사용할때는 gdk내부에 크리티컬섹션을 만들어 줘야 함

(외부 thread에서 gtk 함수 콜하는 모든 부분을 저렇게 보호)

근데 원인이 뭘까?

위젯값들은 전역에 static으로 선언 해서 위젯 포인터 받은이후는 바뀔일은 없을텐데...

gdk 이벤트 관련해서 문제가 생기나....

으아아아아...

핀트는 좀 다르지만.
3년전에 내 블로그에 이 내용 썼구나...

바보 인증 ㅠㅠ
http://lowid.tistory.com/entry/gtk-Thread

다음 부터는 내 블로그 먼저 검색해봐야 겠다.......

7월 18일 "제목" 작성, 7월 31일 발행

오늘도 실수.. iconv

문자열을 변환하는데.. "춏" 이런 글자가 나오면 문제가 생기길래..

로케일 문자에러가 생긴다는 생각은 했는데...

암튼 막 문제가 생기는거 같은 부분을 쭉쭉 타고 역으로 올라가다보니깐 (한시간 더 찾았다 -_-)

perror(); 써서 확인해보니깐
"부적절하거나 불완전한 다중바이트 또는 광역 문자" 라는 메세지가 뜨고.....

그래서 설마 하며 #define한걸 보니

#define LRC_FILE_LOCALE    "EUCKR //IGNORE"         /*  */
#define PRINTED_LOCALE     "UTF8"          /*  */

UTF8 => EUCKR로 변환하는건 옵션을 붙였는데
EUCKR=> UTF8로 변환할때는 옵션을 안붙였네 아놔...

아나 iconv_open 하는 부분의 //IGNORE 가  빠져 있음 ....

//IGNORE  추가....
#define PRINTED_LOCALE     "UTF8 //IGNORE"          /*  */

결국엔

iconv_open("EUCKR //IGNORE", "UTF8 //IGNORE"); // 이런식이 되시겠다.... 맞나 이게...

맨 페이지 아저씨는 이렇게 말씀하셧따.

       //TRANSLIT
              When  the  string  "//TRANSLIT"  is appended to tocode, transliteration is activated.  This means that when a character cannot be represented in the target
              character set, it can be approximated through one or several similarly looking characters.

       //IGNORE
              When the string "//IGNORE" is appended to tocode, characters that cannot be represented in the target character set will be silently discarded.

- 요약하자면... 그냥 로게일 뒤에
"//IGNORE" 써주면 인식 못하는 문자는 무시한다는거구
"//TRANSLIT"는  iconv_open이 비슷한 문자를 알아서 때려넣어(?) 준다는것

오늘의 병신짓 ㅜㅜ.. 이젠 출력되다가 중간에 끊어먹는 버그 해결

에휴 시간 아까워...

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

포인터 연습  (6) 2011.05.27
간단한 디버그 함수  (0) 2010.08.16
아아 또 실수~!  (4) 2009.06.22
주의력 부족  (2) 2009.06.22
이진트리를 만들고나서....아 망했어요...  (2) 2009.05.25

mmap 사용시 알아둘 사항 (버스오류)


mmap  이라하면... seek 같은 귀찬은짓 안하고 파일에서 메모리로 사상 받은다음에,

그 메모리를 조작하면 자동(?) 으로 그 (메모리에 변경된 내용)이 파일에 저장되는 참 편한 넘이져.

(꼭 파일 디스크립터가 있어야하는건 아니지만.......)

근데 문제는,,,저 int files의 파일/파일 디스크립터를 open 할떄 주의 해야하는게...

NAME  
       mmap - map pages of memory

SYNOPSIS
       #include <sys/mman.h>

       void *mmap(void *addr, size_t len, int prot, int flags. int fildes, off_t off);

mmap을 사용할때는 Target 이 되는 파일이 write할 길이보다 커야한다. 는거........

(그러므로 (아래서도 적었지만) 당연히 파일크기가 0가 되서는 안됨)

만약 그렇지 않다면 "버스 오류" 라는 메세지를 출력하고 프로그럄이 종료되어버리는 문제가 생긴다.

O_TRUNC 같은 옵션을 open 함수 사용할때 놓어서도 안되므로 주의 하도록 하자,

그니깐 정리하면.... "mmap은 쓸파일의 크기를 변경할수 없다" 는것..

버스 오류가 나면 참고하도록하자.

joinc에 주의사항하나 정도는 적혀있을듯 했었는데.. 없었던거 같다 (아님 내가 제대로 안읽었던가)

kldp에는 비슷한 내용의 글타래가 올라왔던거 같으니깐 구글에서 찾아보세염.

이걸 왜 했냐면......----------------------------

euckr로 변환된 문서를 utf8로 적용하려고, iconv를 쓰다보니...문제가 생겼다

버퍼 크기가 작어서(euckr로 잡으니) 로케일이 변경되다가 말았던것....

저번엔 utf8->euckr로 변경할때는 어짜피 파일크기가 utf8크기가 크니깐, 그냥 utf8파일 크기를 버퍼 크기로 줘도

상관없었는데, 문제는 그 반대의 상황이 문제였던것...

그래서 메모리 사상을 써봐서 해결해 볼까.......... 해서 mmap을 쓸려고 하니깐....

뭐야... 이것도 결국 버퍼 크기 알아야 하잖아... 챗...

그냥 iconv 함수 쓸때 euckr파일크기 * 2 (사실 1.5배만 해도 충분하다고 하지만) 로 최대 버퍼 잡아서 넘겨버렸다..

(http://kldp.org/node/68263)

잘 되네 변환..

이제 터미널에서 글자폭을 알아야 할 차레...

(뭐 정안되면 UTF8용으로 글자폭 알아보던 함수를 다시 한번 수정해야겠다.

지금 만든건 CJK(한글, 한문, 히라/가타카나)는 글자폭을 제대로 알아오는데.............

러시아어(...) 같은건 제대로 못얻어 와서....... wscol인가.. 그건 왜 눅스에 없을까...)

에이 걍 터미널에서 삽질하지 말고 gtk로 ...?..

아아 또 실수~!

wchar_t* Game_Word_AnsRandom(UINT ch_cnt)
{
    wchar_t *ret;

    // string 이기때문에 NULL을 위해
    if((ret = (wchar_t*)calloc(ch_cnt + 1,sizeof(wchar_t))) == NULL)
        return NULL;

    srand(GetTickCount());
    
    while(ch_cnt >= 0){
        ret[ch_cnt] = (wchar_t)rand()%26 + 97;
        ch_cnt --;
    }

    MessageBox(NULL,ret,0,0);
    return ret;
}

아 또 실수 했어요 ...

이번엔 그래도 디버거가 제대로 작동했기때문에, 금방 알아냈답니다 ㅋㅋ..

게다가 상큼하게 세그멘테이션 폴트도 내 주는바람에 더 쉽게 찾을수 있었죠..

하지만 이런경우는 저도 처음이라서 첨엔 쪼금 당황했는 (한 3분 걸렸 ㅋㅋ)

확실히 이렇게는 안써보니깐 좀 미묘하군요 ㅋㅋ.

데이터 타입의 향연인가... 앞에 포스팅도 그렇게 이것도 그렇고 ㅋㅋ..

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

간단한 디버그 함수  (0) 2010.08.16
오늘도 실수.. iconv  (0) 2010.06.24
주의력 부족  (2) 2009.06.22
이진트리를 만들고나서....아 망했어요...  (2) 2009.05.25
리눅스용 한글2008 체험판 크랙하기  (26) 2009.04.26

주의력 부족

아아. 전 역시

"여러개 있는거 중에서 다른거 찾기 같은거" 정말 못하는거 같습니다

특히 "물건찾기" 같은건 진짜 못합니다.

내가 어디두고 왔는지도 모르겠고, 찾지도 못하겠고...

몇일동안 애를 먹인게 있었습니다.

단어에다가 별표의 위치를 랜덤으로 찍는 그런 함수를 만들고 있었는데, 그렇게 하기 위해서는

랜덤한 숫자들을 가변배열에다가 저장할필요가 있어서 따로 메모리 할당을 받았더랍니다

그런데 이상하게 이게 프로그램이 돌다보면 갑자기 죽어버리는 현상이 생기는겁니다

위치도 딱 거기라고 찍을수가 없을정도로 가변적이였어요.

어쩃던 브레이크 포인터를 건 다음에 벅으를 잡으려고 삽질 ㅋ...

<ERROR>
    int *random_value,
        i,
        j,
        hidden_number_cnt    = -1,
        word_len            = -1;

    wchar_t *word_cp = (wchar_t*)0x0011;

    if((word_len = wcslen(word)) <= 0)
        return NULL;

    if((word_cp = wcsdup(word)) == NULL) // 쳐 죽는 위치 여기서 브레이크 포인터 증발 (합수종료)
        return NULL;                                   // 여기도 브포를 걸었지만 여기 안걸림, 즉 wcsdup에서 GG

    // 단어가 3이하일때 체크해줄것(무시한다던가) - 이함수 call한데서
    if(word_len < 4)
        hidden_number_cnt = 1;
        //return NULL;
    else if(word_len == 4 || word_len <= 5)
        hidden_number_cnt = 2;
    else if(word_len == 6 || word_len == 7)
        hidden_number_cnt = 3;
    else if(word_len >= 8 && word_len <= 10)
        hidden_number_cnt = 4;
    else if(word_len > 10)
        hidden_number_cnt = 5;  

    // windows에서는 가변배열 설정이 안되니 이렇게 하자
    if((random_value = (int*)calloc(hidden_number_cnt,sizeof(wchar_t))) == NULL)
        return NULL;

저기서 갑자기 주거 버리니깐 어어어 왜그런거얌. ㅜㅜ

이러고 위에 wcslen, wcsdup 함수 부분만 눈에 불을 켜고 찾아보았습니다

혹시해서 인자들 다 념어온거(리스트로 생성한) 틀렸나 확인을 해보았는데...... "다 맞 잖 아 !!!"

아 정말 저기서 저것만 미친듯이 보고보고보고보고 또 봐도 안되길래

미친듯이 여기 저기 주석을 쳐가면서 범위줄이기를 한결과

......
    for(i = 0;i < hidden_number_cnt ;i ++){
            //random_value[i] = rand() % word_len;   // 넌 꺼지고
            random_value[0] = rand() % word_len;     // 얘로 하니깐
......

아래 내용을 조금 바꾸니깐 잘되는겁니다!! (여기서 잘된다 == 안죽는다!)

그래서 오오오 여기가 "에 러 위 치 구 나 ㅋ" 했더니만...

또 아~무리 봐도 여기서 죽을 이유가 없어요 단지 i를 0으로 바꾼거 뿐이라니까?

hidden_number_cnt 변수가 이상한값 들어갔나 봐도 뭐 (당연히) 정상이고..

아놔 뭥미하다가 아까꺼 다시보니....

어?

<OK>
    // windows에서는 가변배열 설정이 안되니 이렇게 하자
    if((random_value = (int*)calloc(hidden_number_cnt,sizeof(int))) == NULL)
        return NULL;

우왕ㅋ wchar_t 라고 적어왔엉... int인데... int인데.. int인데...

저거 고치니깐 조난 잘돌아가네여 ㅜㅜ x 100

단 "한 단어" 차이인데 ㅜㅜ...

*오늘의 교훈*

1 디버거를 넘 믿지 말자.
- 특히 디버깅 위치에 너무 연연하지 말자 솔까말 저 디버깅 정보로 원래 문제가 된 부분을 절대 찾을수가 없엉ㅋ.

2 예측하지못한 에러(갑자기 사망!) 하는 경우는, 거의 100%에 가깝게,
잘못된 메모리 참조가 그 원인이다.

- 물론 (*) 참조 말고 전체적인 참조를 다 말하는거...(위에 경우에는 타입이 문제였죠)
그러고 보니 calloc에 강제로 타입케스팅을 해줬으니 컴파일러도 눈치 못챘겠네 ㅜㅜ

3 삽질엔 장사없다

교훈을 쓰자마자 동시에 난 자괴감에 빠짐.......

우어어어어엉? 저딴걸 내가 몇일씩 붙잡고 있었단 말이야?  이함수 60줄 정도 밖에 안

되는데 겨우 저걸로? 저걸로? 그럴리겅ㅄ엉ㄴ리ㅏㅁ나ㅣ루나ㅣㅇ라ㅣ

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

오늘도 실수.. iconv  (0) 2010.06.24
아아 또 실수~!  (4) 2009.06.22
이진트리를 만들고나서....아 망했어요...  (2) 2009.05.25
리눅스용 한글2008 체험판 크랙하기  (26) 2009.04.26
이거 왜이래~!  (6) 2009.04.02
prev 1 2 3 4 5 6 next