Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wywołanie metody system oraz zapisanie jej do zmiennej

Ostatnio zmodyfikowano 2023-05-07 22:51
Autor Wiadomość
dunno
Temat założony przez niniejszego użytkownika
Wywołanie metody system oraz zapisanie jej do zmiennej
» 2023-02-19 11:27:56
W jaki sposób mogę wywołać polecenie za pomocą system() i jej wartość zapisać do zmiennej?
Zrobile cos takiego:
 int32_t how_much_ram_available_now = int32_t(system("free -m | awk 'NR==2'|awk '{ print $7 }'"));
 std::cout << "how_much_ram_available_now: " << how_much_ram_available_now << std::endl;
ale niestety wypisuje mi how_much_ram_available_now = 0;
Myślałem, że być może wartość zwracana przez polecenie system jest typu string, ale niestety na kilka możliwych sposobów nie mogłem zapisać tej wartości do zmiennej. Oczywiście jak to samo polecenie wpiszę w konsoli to wypisuje mi ilość pamięci ram jaka jest dostępna.

P-179964
DejaVu
» 2023-02-19 11:57:20
Polecenie system daje Ci możliwość wywołania polecenia, ale nie daje możliwości odczytania tego co na ekran konsoli zostanie wypisane. Patrz dokumentacja:
https://man7.org/linux/man-pages/man3/system.3.html
P-179968
pekfos
» 2023-02-19 13:38:20
P-179970
dunno
Temat założony przez niniejszego użytkownika
» 2023-05-03 11:25:26
Dzięki, spróbowałem coś takiego
C/C++
#ifdef EMERGENCY_SHUTDOWN
void Game::checkEmergencyShutdown()
{
   
OTSYS_THREAD_LOCK_CLASS lockClass( gameLock, "Game::checkEmergencyShutdown()" );
   
int32_t how_much_ram_available_now = 0;
   
   
FILE * fp;
   
int32_t status = 0;
   
char path[ PATH_MAX ];
   
   
fp = popen( "free -m | awk 'NR==2'|awk '{ print $7 }'", "r" ); // $7 = ram available
   
if( fp == NULL )
       
 std::cout << "Handle Error [checkEmergencyShutdown]" << std::endl;
   
   
//while (fgets(path, PATH_MAX, fp) != NULL)
    //printf("%s", path);
   
   
if( fgets( path, PATH_MAX, fp ) != NULL )
   
{
       
how_much_ram_available_now = atoi( path );
   
}
   
   
status = pclose( fp );
   
if( status == - 1 ) {
       
std::cout << "Error reported by pclose()" << std::endl;
   
}
   
else
   
{
       
/* Use macros described under wait() to inspect `status' in order
     to determine success/failure of command executed by popen() */
       
if( how_much_ram_available_now < g_config.EMERGENCY_RAM_AVAILABLE && how_much_ram_available_now != 0 )
       
{
           
//---MONITORING---
           
sheduleShutdown( 5 );
       
}
       
else
       
{
           
addEvent( makeTask( 1000 * 60, std::mem_fun( & Game::checkEmergencyShutdown ) ) ); // co 60 sekund wywolaj ta funkcje do sprawdzenia
       
}
    }
}
#endif  //EMERGENCY_SHUTDOWN

Testowałem przez jakiś czas i działało, a teraz nagle powoduje crasha - pełne logi gdb: https://pastebin.com/fDiQ4HCX.
#1  0x565dc0fa in Game::checkEmergencyShutdown (this=0x5677ad60 <g_game>) at game.cpp:9598

linijka 9598 którą wskazuje to
if (fgets(path, PATH_MAX, fp) != NULL)

a w praktyce domyslam sie ze wywala w tej wcześniej. Zrobiłem sobie "checkpointy" no i wywalilo mi:
Handle Error [checkEmergencyShutdown]

tak jakby nie moglo wywolac tej komendy lub dostało NULL i crash. Nie wiem czemu nie moglo tej komendy wywolac.
Ja chciałbym żeby w razie niepowodzenia po prostu przeszlo do:
addEvent(makeTask(1000*60, std::mem_fun(&Game::checkEmergencyShutdown))); // co 60 sekund wywolaj ta funkcje do sprawdzenia


Jakieś pomysły co zrobiłem nie tak?
P-180126
pekfos
» 2023-05-07 22:51:12
tak jakby nie moglo wywolac tej komendy lub dostało NULL i crash. Nie wiem czemu nie moglo tej komendy wywolac.
Może z braku RAMu? W końcu próbujesz tu uruchomić dodatkowe procesy. Dobrze by było logować także kod błędu.

Ja chciałbym żeby w razie niepowodzenia po prostu przeszlo do:
To dopisz takie zachowanie, zamiast ignorować błąd.
P-180133
« 1 »
  Strona 1 z 1