Вид в Linux для столбца, сохраняя другие значения в целости

Что автор подразумевает под стеками здесь? Я делаю программирование Java и знаю, что каждый поток получает свой собственный стек. Таким образом, я смущен общим понятием стеков здесь.

Использование множественного числа там немного нечетно, и это действительно кажется вводящим в заблуждение, возможно дело в том, что несколько стопок многопоточной программы совместно используют то же адресное пространство.

Как Bruce Ediger описывает, "стек" относится к единственному региону непрерывного адресного пространства, в которое данные помещаются мудрые LIFO. Однако каждый собственный поток в процессе имеет такой непрерывный регион - нет того, разделенного между каждым из них. Создание потока действительно требует выделения дополнительной стопки того же размера (это - постоянное число, например, значение по умолчанию на Linux составляет 8 МБ), который является, почему чрезмерно многопоточные приложения могут использовать чрезмерные объемы памяти.

Java использует собственные потоки для реализации потоков Java, но он справляется, "стек" для каждого Java распараллеливает себя, независимый от ядра. Это означает откладывать некоторую глобальную память для использования с этой целью; посмотрите третью часть главного ответа здесь:

https://stackoverflow.com/questions/5483047/why-is-creating-a-thread-said-to-be-expensive

Конечно, это относится к определенной реализации (openjdk), но по-видимому они все должны сделать это (выделите "кучу" исходно для внутреннего пользования как "стопка потока").

Так как отдельным стеком, используемым каждым собственным потоком, управляет ядро, я не соглашаюсь с импликацией Bruce, что это - часть некоторого полного стека, принадлежащего процессу в целом - снова, сингл (иначе не-) распараллелил процесс, только имеет один стек, но основной поток в многопоточном процессе не совместно использует стековое пространство с другими потоками.

"Общий стек" был бы тем, в котором все данные хранятся, начинаясь с единственного адреса - это - смысл, в котором вызовы вложенной функции совместно используют тот же стек. Однако с помощью настроенной версии примера программы, упомянутого ниже Bruce, от версии Linux pthread_create страницы справочника страницы справочника:

./a.out one two three
In main() stack starts near: 0x7fff17b80f98
Thread 1: top of stack near 0x7f11ac6d3e78; argv_string=one
Thread 2: top of stack near 0x7f11abed2e78; argv_string=two
Thread 3: top of stack near 0x7f11ab6d1e78; argv_string=three

Эта программа берет адрес локальной переменной в потоковой функции; тонкая настройка, которую я добавил, должна была выполнить в том же самом main() прежде чем потоки создаются. Выполнение находится в недавней 64-разрядной системе Linux; заметьте, что начальные адреса для потоков ТОЧНО на расстоянии в 8 МБ, и они очень далеки действительно от вершины основной стопки потока. Контрастируйте это с вызовами вложенной функции как это:

#include 

void eg (int n) {
    char *p;
    printf("#%d first variable at %p\n", n, &p);
    if (n < 3) eg(n+1);
}

int main(int argc, const char *argv[]) {
    char *p;
    printf("main() first variable at %p\n", &p);
    eg(1);
    return 0;
}

Пример выполняется:

main() first variable at 0x7fffef0aaf68
#1 first variable at 0x7fffef0aaf38
#2 first variable at 0x7fffef0aaf08
#3 first variable at 0x7fffef0aaed8

Они всего на расстоянии в 48 байтов - другими словами, они размещаются один за другим непрерывно (с другими небольшими битами фактических данных) без неиспользуемого места между ними. Если мы используем это в многопоточной программе без вложенной рекурсии, но вызова eg() однажды в каждом потоке:

Thread 1: top of stack near 0x7f4bd5061e78; argv_string=one
Thread 2: top of stack near 0x7f4bd4860e78; argv_string=two
Thread 3: top of stack near 0x7f4bd405fe78; argv_string=three
#3 first variable at 0x7f4bd405fe48
#1 first variable at 0x7f4bd5061e48
#2 first variable at 0x7f4bd4860e48

Переменная для каждого около вершины трех отдельных стеков.

Все это находится в высоком регионе адреса, называемом "стековым пространством", но в многопоточной программе, которая разделена на несколько стеков; это не рассматривают как одну большую структуру LIFO.

2
14.02.2014, 21:27
1 ответ

Синтаксис -k<start>[<flags>][,<end>[<flags>]] (если ,<end> опущен, это - конец строки).

Это определяет часть строки к виду на как один ключ сортировки.

<start> и <end> обратитесь к полевым числам. 2 для <start> означает начало 2-го поля, в то время как 2 для <end> означает конец 2-го поля.

По умолчанию поля разграничены переходом между непробелом и пробелом. Например, в:

NODE_154_length  847 2997

Поля:

[NODE_154_length][  847][ 2997]

Выполнение sort -k2, виды со стороны строки, которая запускается в начале 2-го поля и концов в конце строки. Таким образом выше, на [ 847 2997]. sort делает лексические сравнения быть значением по умолчанию.

sort -k2,2 рассмотрел бы только [ 847] для сравнения.

Если Вы хотите сделать числовое сравнение на конкретном ключе, необходимо добавить n <flag> к ключу сортировки. Тот путь,  847 был бы преобразован в число. Вот почему -k2,2n и -k2n работал бы то же потому что оба [ 847] и [ 847 2997] строки преобразовывают в число 847.

Так, для получения первого результата Вы хотите отсортировать на первом поле лексикографически, и затем (где первый полевой вид одинаково) на втором поле численно. Это записано:

sort -k1,1 -k2,2n

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

Это - то, где Вам нужно -s опция для стабильного вида:

sort -s -k2,2n

(по умолчанию, где ключи сортируют то же, sort обращения к выполнению лексического сравнения целой строки; -s отключает это).

6
27.01.2020, 21:54

Теги

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