Názory k článku Programování pod Linuxem pro všechny (9)

  • Článek je starý, nové názory již nelze přidávat.
  • 21. 3. 2004 21:04

    pet (neregistrovaný)

    Mam nasledujici problem, pokud nekdo poradi, budu vazne vdecny!!!

    Pisu si rutinu ve stylu readline, ale pod ncurses (nonl, cbreak, noecho, keypad) - rad bych si odchytaval signal pri zmene velikosti terminalu a prekreslil obrazovku (az sem v pohode). Problem je, ze se mi smycka blokuje na getch(), ktery mi nevrati KEY_RESIZE okamzite, jak by mela, ale ceka az na stisk dalsi klavesy a pak vyvrhne oboji najednou.

    Tohle chovani je zpusobeno tim, ze mam vlastni obsluhu signalu SIGWINCH, to vim. Kdyz ji vyradim, tak getch() pekne KEY_RESIZE vrati hned a neblokuje, ale tim zas prichazim o moznost asynchrone a nezavisle na ty moji "readline" updatovat terminal.

    Jina moznost by byla pouzit nodelay() a getch() by pak neblokovala nikdy, ale tam zas mam problem ze smycka typu:

    while (1) {
    if ((c = getch()) == ERR)
    break;
    ...
    }

    sezere 99% CPU. :(

    Tedy otazky co me trapi a rad bych znal odpoved:
    1) Je mozny z moji obsluhy signalu nejak zavolat tu puvodni, aby vsechno udelala jak ma (tzn, nejak interne uvedomila getch(), ze ma skoncit s KEY_RESIZE)? Zkousel jsem to pres:

    typedef void (*sighandler_t)(int);
    sighandler_t oldsig;

    my_resize_event(int sig) {
    ...
    oldsig(sig);
    signal(SIGWINCH, &resize_event);
    return;
    }

    main() {
    ...
    initscr, atd...
    oldsig = signal(SIGWINCH, &my_resize_event);
    ...
    }

    ale to neudela nic (jako bych ji zevnitr obsluhy vubec nevolal).

    2) Jak vubec retezeni signalu funguje, jsem zvyklej z DOSu na retezeni ve stylu preruseni asm/INT 2F a tak. Jde to nejak podobne v Linuxu na vyssi urovni (C) se signaly?

    3) Jak udelat - obecne - smycku typu co jsem popisoval a pri tom pouzit jen nezbytne nutne _minimum_ casu CPU?

    Uz jsem se ptal na linux@linux.cz, ale nikdo mi zatim nebyl schopen/ochoten odpovedet... :(

    Diky za radu/odkaz!

  • 21. 3. 2004 23:50

    Petr Baudis (neregistrovaný)

    Doporucuji vam dokumentaci k resizeterm(3X). Slo by asi treba proste v signal handleru ungetch()nout KEY_RESIZE, a dalsi getch() by si toho melo vsimnout.

    Co se tyce toho, aby smycky nezraly 99% CPU, lze tomu predejit obecne tak, ze do te smycky umistete nejaky bod, ve kterem se jadro muze zastavit, dokud se nestane "neco zajimaveho", na co cekate.

    Napriklad pokud se chcete zastavit, dokud nedostanete nejaky signal, muzete pouzit pause(). Ve vasem pripade ale spise cekate, dokud se neco neobjevi na standardnim vstupu, tedy cekate na udalost na nejakem filedescriptoru. K tomu muzete vyuzit bud select() nebo poll(), podle chuti :).

  • 22. 3. 2004 14:04

    pet (neregistrovaný)

    1) Dokumentaci a zdrojak ncruses mam nacteny davno a resizeterm() pochopitelne pouzivam. :) Neptal bych se aniz bych byl "v koncich". ungetch() v signal handleru z nepochopitelnych duvodu nejde, prestoze ncursi handler to dela prave tak. getch() si nevsimne.

    2) jasne, select nebo varianta sleep. myslel jsem jestli neni pod Linuxem nejaka jina moznost. diky

    3) ditto.

    Diky za odpoved!