Оперативный вывод прогресса в терминале или консоли

Когда Вы работаете git clone, это обновляет прогресс на месте. Например, процент объектов получил изменения на месте.

user@athena:~/cloj/src$ git clone git://git.boinkor.net/slime.git
Initialized empty Git repository in /home/user/cloj/src/slime/.git/
remote: Counting objects: 15936, done.
remote: Compressing objects: 100% (5500/5500), done.
Receiving objects:  28% (4547/15936), 3.16 MiB | 165 KiB/s

Как это выполняется? Это использует ncurses или что-то еще более простое, как некоторая комбинация символов возврата и регулярного вывода символов?

Я особенно интересуюсь тем, как этот вид консольного вывода мог быть выполнен от Ruby.

Править

На мой исходный вопрос отвечают. Но вот приложение. При использовании MPlayer, например, он не только обновляет строку для показа текущего прогресса, но также и предыдущей строки (например, когда Вы нажимаете паузу).

 =====  PAUSE  =====
A:  79.9 (01:19.9) of 4718.0 ( 1:18:38.0)  0.3% 

Как Вы обновили бы две строки оперативного вывода?

32
задан dan 28 February 2010 в 19:54
поделиться

3 ответа

Вот один. Ключи заключаются в том, что имеется три буфера, и считывающее устройство резервирует буфер, из которого оно считывает. Устройство записи выполняет запись в один из двух других буферов. Риск столкновения минимален. Плюс, это расширяется. Просто сделайте массивы участников на один элемент длиннее, чем количество считывающих устройств плюс количество записывающих устройств.

class RingBuffer
{
  RingBuffer():lastFullWrite(0)
  { 
    //Initialize the elements of dataBeingRead to false
    for(unsigned int i=0; i<DATA_COUNT; i++)
    {
      dataBeingRead[i] = false;
    } 
  }

  Data read()
  {
    // You may want to check to make sure write has been called once here
    // to prevent read from grabbing junk data. Else, initialize the elements
    // of dataArray to something valid.
    unsigned int indexToRead = lastFullWriteIndex;
    Data dataCopy;
    dataBeingRead[indexToRead] = true;
    dataCopy = dataArray[indexToRead];
    dataBeingRead[indexToRead] = false;
    return dataCopy;
  }

  void write( const Data& dataArg )
  {
    unsigned int writeIndex(0);

    //Search for an unused piece of data.
    // It's O(n), but plenty fast enough for small arrays.
    while( true == dataBeingRead[writeIndex] && writeIndex < DATA_COUNT )
    {
      writeIndex++;
    }  

    dataArray[writeIndex] = dataArg;

    lastFullWrite = &dataArray[writeIndex];
  }

private:
  static const unsigned int DATA_COUNT;
  unsigned int lastFullWrite;
  Data dataArray[DATA_COUNT];
  bool dataBeingRead[DATA_COUNT];
};

Примечание: Как это написано здесь, есть две копии для чтения ваших данных. Если передать данные из функции чтения через ссылочный аргумент, можно сократить их до одной копии.

-121--4529228-
  • Может быть много действующих лиц. Все актеры действуют «одновременно». Параллелизм является ключевой частью этой модели.

  • Актеры не могут знать, что думают другие Актеры. Единственный способ перемещения информации - это сообщение. (нет общего состояния)

  • Субъекты могут принимать сообщения и действовать по ним,

    • выполняя вычисления с данными в них

    • посылая сообщения другим субъектам

    • создавая других субъектов.

    • игнорирование/отмена сообщения.

Это в основном делает актеров так же, как... Люди. Люди не знают, что думают друг о друге, они должны посылать сообщения, чтобы передать информацию, у них есть выбор игнорировать входящие сообщения, рассматривать их или общаться с другими людьми. Случайные плохие вещи могут случиться с людьми. Многие делают вещи одновременно. Чтобы обрабатывать больше нагрузки, добавьте больше пользователей.

Что касается вашего генерального проекта, я предлагаю узнать о веб-платформе Erlang. Язык программирования Erlang основан на модели Actor и используется для достижения больших результатов в масштабируемых системах, включая телефонные коммутаторы... и системы обмена сообщениями Facebook .

-121--3302840-

Использовать возврат каретки. Обычно '\r 'должен работать.

38
ответ дан 27 November 2019 в 20:47
поделиться

git / progress.c

...
        eol = done ? done : "   \r";
...
                fprintf(stderr, "...%s", ..., eol);
                fflush(stderr);

Git просто выдает возврат каретки без перевода строки, что терминал интерпретирует как «перейти к первому столбцу».

7
ответ дан 27 November 2019 в 20:47
поделиться

Для Ruby существует ряд библиотек curses. Я считаю, что rbbcurse самый популярный.

0
ответ дан 27 November 2019 в 20:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: