тл;др; протокол X11 не имеет понятия о процессах, сигналах или каких-либо IPC; и сервер, и любой из его клиентов могут находиться на разных машинах и в разных операционных системах, которые могут просто не иметь представления о процессах вообще (во время разработки протокола X11 машины на Лиспе все еще существовали ). Сам протокол X11 может работать поверх сокетов unix, tcp/ip или туннелироваться через ssh и т. д.
Существует 3 способа «закрыть» окно X11:
Отправить событие ClientMessage
с атомом WM_DELETE_WINDOW
в это окно.Приложение, создавшее это окно, может воздействовать на него (, например. xclock
, xeyes
просто выйдут; другие могут закрыть это окно и продолжить работу )или проигнорировать его. Это то, что обычно происходит, когда вы нажимаете кнопку X
или нажимаете какую-либо «стандартную» комбинацию клавиш, например Alt-F4
.
Принудительно уничтожьте это окно с помощью XDestroyWindow
. Приложение может не ожидать этого и может игнорировать любое событие DestroyNotify
и по-прежнему пытаться выполнять операции с этим окном, как если бы оно все еще существовало, что приведет к получению XErrorEvent
с кодом, установленным на BadWindow
. Обработчик ошибок по умолчанию из Xlib (, установленный с XSetErrorHandler
), выведет сообщение об ошибке и в этом случае выполнит очистку exit(3)
.
Вызовите XKillClient
в этом окне, что принудительно закроет создавшего его клиента (вместо окна можно использовать любой ресурс X11, например. XID
растрового изображения ). Это то, что xkill(1)
делает [1]. Это не имеет ничего общего с kill(2)
или kill(1)
и не отправляет никакого сигнала какому-либо процессу. Если клиент не принял специальных мер, (см.XSetCloseDownMode(3)
)все созданные им ресурсы (окна, растровые изображения, графические контексты )будут уничтожены. Опять же, обработчик ошибок Xlib io по умолчанию (, установленный с помощью XSetIOErrorHandler
), выведет сообщение об ошибке и выполнит очистку exit(3)
и в этом случае. Отличие от пт. 2. заключается в том, что обработчик, установленный с помощью XSetIOErrorHandler
, может не возвращать .
Некоторые приложения довольно раздражающе воспринимают 2. и 3. как «сбой» (, например. firefox, который покажет свое печально известное сообщение «Ну, это смущает» при следующем запуске, если только browser.sessionstore.resume_from_crash
не установлено в false ).
Кроме того, приложение не может узнать, было ли оно удалено с сервера с помощью XKillClient
или сам сервер неожиданно закрылся или произошел сбой.
Еще один момент, который стоит повторить, заключается в том, что протокол X11 кооперативный по замыслу; между клиентами X11 нет барьеров и проверок;любой клиент может выгнать любого другого клиента с помощью XKillClient
, уничтожить его окна или изменить их размер, полностью захватить клавиатуру или мышь, установить флаг переопределения перенаправления, чтобы убрать оконный менеджер с дороги, и т. д.
[1] Если вы не используете reparenting wm, вы должны использовать xkill -frame
, чтобы он работал.
Ваша функция max
выполняется за O (n^2 )для первых 500 значений в Bash. Скорее всего, это связано с тем, что вы вызвали max
с оставшимися значениями. Таким образом, эти значения должны быть скопированы.
mmax() {
max $(seq $1)
}
seq 10000 | env_parallel --joblog bash.log mmax
(echo '#Bash';echo '#JobRuntime in seconds';field 10,4 < bash.log |sort -n) |
head -n 1000 | plotpipe
Для первых 1000 значений картина немного более мутная:
Для ksh
первые 500 значений не очень понятны:
Но для 1000 значений это также выглядит как O (n^2):
ksh
вылетает на 1237:
(plotpipe
и field
из :https://gitlab.com/ole.tange/tangetools).