Страницы

Поиск по вопросам

воскресенье, 21 октября 2018 г.

Как сравнить производительность разных виртуальных машин?

Пытаюсь выбрать виртуальную машину, и не могу понять как их сравнивать. Когда читаю описание любой ВМ - вижу много слов про используемые технологии, и почему они делают эту ВМ самой быстрой. Но ведь не могут все они быть самыми быстрыми, какие-то из них же должны быть быстрее других?
Как сравнивать разные виртуальные машины?


Ответ

1. Наиболее быстрыми являются виртуальные машины контейнерного типа - все контейнеры используют общее ядро и общие модули уровня ядра, но служебные структуры каждого процесса инициализированы особым образом, что создает иллюзию совершенно разных серверов.
Примеры контейнеров - OpenVZ, Docker. Работают только на линуксе, потому что над другими ОС невозможно надругаться настолько же сильно.
2. Следом за контейнерами в порядке уменьшения производительности идет паравиртуализация. Паравиртуализация - это запуск гостевой ОС полностью на уровне пользователя, для этого для нужной ОС готовят специальные драйвера, которые подменяют все те модули ядра, которым ранее требовался доступ к привилегиям уровня ядра (ring 0 на архитектуре x86/64).
Пример паравиртуальных машин - XEN, User mode linux.
Ограничение - гостевая ОС для работы в паравиртуальном режиме должна быть совместима с используемым гипервизором. Зачастую это ограничение можно читать как "гостевая ОС должна быть линуксом", хотя есть и некоторые исключения.
3. Следующие по тяжести реализации - гипервизоры, использующие аппаратную виртуализацию. Это опять XEN, KVM, VirtualBox, WMWare, Hyper-V и QEMU (в режиме KQEMU)...
Здесь уже нет никаких ограничений на гостевую ОС, кроме наличия под нее драйверов для виртуальных устройств. Но многие реализации эмулируют в качестве "виртуальных" реально существующие устройства, что упрощает проблему с драйверами.
Но тут надо понимать, что несмотря на возможность полной виртуализации на каждой из этих ВМ, все они могут использовать частичную паравиртуализацию для ускорения работы. Поэтому если поставить на ВМ специальный набор "гостевых" драйверов - ее работа ускорится и могут появиться новые возможности. Поэтому при выборе ВМ надо учитывать предполагаемую гостевую ОС и смотреть, какие гостевые драйвера для нее есть.
Обычно считается, что XEN, KVM и VirtualBox быстрее работают когда гостевая ОС - linux, а WMWare и Hyper-V - когда гостевая ОС - Windows.
4. Последний класс, самый медленный - эмуляторы. Снимают ограничение по архитектуре процессора (можно эмулировать ARM на x64 или наоборот) - но работают еще медленнее прошлых классов. Пример - QEMU, BOCHS.
У эмуляторов тоже есть приемы для ускорения выполнения. Но сравнение эмуляторов выходит уже за рамки этого вопроса.

Условие If в лямбда выражении

Есть конструкция вида List> которая используется для формирования строки. Строку формирую так
var val = String.Join(",", insert_res.Where(d => d.Item3 == 0) .Select(d => "'" + d.Item2 + "'"));

Но в зависимости от значения второго строкового параметра мне надо возвращать не в кавычках "'" + d.Item2 + "'", а например в круглых скобках, возможно поместить туда проверку?


Ответ

Есть несколько вариянтов.
Можно использовать тернарный оператор:
var val = String.Join(",", insert_res .Where(d => d.Item3 == 0) .Select(d => condition ? "'" + d.Item2 + "'" : "(" + d.Item2 + ")"));
Тоже можно использовать ламбда блок вместо ламбда выражения:
var val = String.Join(",", insert_res .Where(d => d.Item3 == 0) .Select(d => { if (condition) { return "'" + d.Item2 + "'"; } return "(" + d.Item2 + ")"; }));

Анализ сборок дотнета

Мне необходимо при загрузке дотнет сборки (в виде файла, или набора байтов) на мой сервис получить публичный ключ, которым она подписана, каким образом мне это можно сделать?
Что я пробовал:
Загрузить через Assembly.Load её я не могу, так как у неё могут быть зависимые сборки которые тоже должны быть загружены (а их у меня нет). Создать временный аппдомен, загрузить в него сборку через Assembly.ReflectionOnlyLoad (через маршалинг .DoCallback), а затем выгрузить аппдомен после извлечения публичного ключа. Тут я сталкиваюсь с тем, что даже если я выгружаю аппдомен - у меня периодически падает загрузка пересобранной сборки с той же версией (например для другого фреймворка).


Ответ

Вы можете использовать для этого библиотеку Mono.Cecil которая так же доступна через NuGet.
var assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly("fileName"); var publicKey = assembly.Name.PublicKey;

Почему PhpStorm 10.0.1 зачеркивает функции с префиксом mysql_?

PhpStorm не распознает код mysql. Если просто сохраняю проект в notepad то все работает, а когда тот же проект копирую (пишу) в PhpStorm, он зачеркивает команды подключения к mysql. На скрине видно:

PhpStorm настроен с openserver. Может в этом проблема? Что-то еще нужно добавить? Хотя если прямо подключиться к БД из PhpStorm, то все работает нормально.


Ответ

Выдержка из документации
Внимание Данное расширение устарело, начиная с версии PHP 5.5.0, и будет удалено в будущем. Используйте вместо него MySQLi или PDO_MySQL
Прислушайтесь к процитированному совету.
Относительно вашего вопроса: таким образом PhpStorm сигнализирует о том, что вы пытаетесь использовать устаревшие функции, которые будут в будущем удалены.
Эти предупреждения никак не влияют на функциональность вашего приложения. Если не работает подключение к базе данных, вам следует проверить используемую версию PHP.

Что означает “There is 1 zombie process” и что с ним делать?

Залогинился на удаленную машину. Вижу следующую строку в приветственном сообщении.
There is 1 zombie process.
Насколько я понял, это означает, что какой-то процесс завершил работу, но не закрылся и не освободил ресурсы. Хотелось бы лучше понять проблему:
Как можно его обнаружить? Сейчас я угадал, но нужен стабильный метод. Как можно узнать причины его появления? Есть какие-нибудь логи? Может, по имеющемуся процессу можно что-либо понять?
Если это важно, ubuntu 14.04, sudo есть.
Дополнение: меня не устраивает метод «просто подождать», т.к. есть сервис, который должен работать всегда — и подвис он или кто-то из его детей. Он подстрахован monit'ом, но тот не распознал зомбификацию и не перезагрузил.


Ответ

Зомби в операционных системах UNIX называют завершившиеся процессы, код завершения которых не забрал родительский процесс. Зомби не потребляют никаких ресурсов, память и файловые дескрипторы таких процессов уже освобождены. Остается только запись в таблице процессов, которая занимает несколько десятков байт памяти. Так что единичный зомби процесс на систему никак не влияет. НО он явный индикатор того, что у какого то процесса в системе что то пошло не так.
Поиск зомби:
ps -axho state,pid,ppid | grep Z | sed 's/./ps/' | sh
Данная команда покажет все зомби процессы и их родителей (тестировалась под linux, под другими *nix возможны другие ключи у команды ps).
Убить зомби можно только перезапуском родительского процесса. kill -9 самого процесса-зомби и чеснок обычно не помогают. Если появление зомби разовое явление, то возможно проще на факт его появления забить.
Что бы понять почему именно появился зомби надо смотреть исходники породившего его процесса и возможно самого зомби. Часто это одна и та же программа. Любой процесс, выполняющий fork, т.е. запускающий дочерние процессы должен уметь забирать код их завершения, делается это вызовом wait и/или waitpid. Для начала надо просмотреть исходники на наличие функций группы wait, а так же наличие функции-обработчика сигнала SIGCHLD (обработчик устанавливается вызовом signal и функций для работы с сигналами потоков). Если родитель не использует функции группы wait, то возможно при его нормальной работе завершение дочерних процессов разработчик вообще не ожидал. Если это так - то причина образования зомби - незапланированное завершение процесса потомка в следствие какой либо ошибки. Дать рекомендаций как это искать и лечить невозможно. Можно только посоветовать добавить в родительский поток обработку CHLD, забор кода завершения с помощью wait и логирование факта завершения потомка. И дальше запуск потомка под отладчик и т.п. ...
Вариант 2: родительский процесс использует wait, но зомби все равно появляются. Копать в сторону того, какая разновидность wait используется, если waitpid, которая проверяет завершение конкретных потомков, то смотреть откуда она берет проверяемые pid, возможно в процессе работы какие то pid потомков теряются и программа про них забывает. Может программа в какой то момент запрещает обработку сигналов и забывает восстановить обработку, после прохождения критического участка. Опять же - вариантов очень много, но сосредоточены они вокруг обработчика SIGCHLD и функций wait
Вариант 3: родительский процесс умеет обрабатывать и готов правильно обработать завершение своих потомков. Но зацикливается в другом месте программы или засыпает на системном вызове, например чтения с сетевого диска, который стал недоступен и при этом прерывание по SIGCHLD запрещено. В этом случае надо разбираться с причинами его зависания. Кстати, отсутствие доступа к каким либо ресурсам, типа сетевых дисков (или при выходе из строя физического диска) - довольно частая причина массового появления зомби.
Каких либо специальных логов в системе, где можно было бы увидеть хоть какую то информацию по появляющимся зомби не существует. Следы можно найти только в логах той программы, которая их порождает, при их наличии.

Как перенести проект C# из Visual Studio в среду gnu/linux?

Имеется виндовый проект в visual studio, надо перенести его на дистрибутив ubuntu операционной системы gnu/linux.
Как я понимаю, надо первым делом избавится от windows forms и сделать консольный интерфейс. Это сделаю.
Проблема в том что в проекте используется сторонняя библитотека dll (для подключения и работы с внешней БД mysql) Её можно каким-либо образом перенести или следует искать алтернативу под gnu/linux?


Ответ

Как я понимаю, надо первым делом избавится от windows forms
Mono ж вроде имеет свою реализацию Winforms, совместимую по крайней мере процентов на 99. Говорят так. Что же до WYSIWYG, то в штатной IDE нету его для Winforms, только для GTK#, но можно скачать и поставить MWF Designer.
Проблема в том что в проекте используется сторонняя библитотека dll
И опять же, как и с Winforms: почему вы уверены, что она не пойдет на Mono?Библиотека для работы с БД теоретически могла бы хоть на утюге или микроволновке работать, если ОЗУ и ПЗУ хватит. Ничего платформозависимого там не должно быть. (Исключение - ADO.NET и иже с ним, но это не совсем библиотека под .NET, оно завязано на нативном виндовом ADO)Попробуйте написать MySQLьный хелловорлд на Mono - судя по всему, в вашем случае следует начать с этого.

python3, удаление “подсписка” из списка

Нужно удалить из списка в вхождения, да не просто по элементам, а прям множество. Т.е. если есть список: [0, 1, 2, 3, 1, 5, 3, 7], и например, кортеж, который удаляемых элементов (1, 5, 3), нужно, чтобы в итоге получился список [0, 1, 2, 3, 7]. Как можно легче всего такое реализовать?


Ответ

Я бы попробовал что-то вроде такого: 1) изменение списка на месте (чуть сложнее)
def is_equal(lst, pattern): if len(lst) != len(pattern): return False for a, b in zip(lst, pattern): if a != b: return False return True
def clear_list(lst, pattern): index = [] l = len(pattern) rng = iter(xrange(len(lst))) while True: try: i = next(rng) if is_equal(lst[i:i+l], pattern): for j in range(i, i + l): index.append(j) if j != i + l - 1: next(rng)
except StopIteration: break index.reverse() for i in index: del lst[i]
l = [1, 2, 1, 2, 1, 1, 2, 1, 3, 4, 1] p = (1, 2, 1) clear_list(l, p) print l # --> [2, 1, 3, 4, 1]
Оно даже работает.

2) для генерации нового списка (все проще):
def clear2(lst, pattern): res = [] l = len(pattern) r = iter(xrange(len(lst))) while True: try: i = next(r) if is_equal(lst[i:i+l], pattern): for j in range(i, i + l - 1): next(r) else: res.append(lst[i]) except StopIteration: break return res
l = [1, 2, 1, 2, 1, 1, 2, 1, 3, 4, 1, 2] p = (1, 2, 1) print l print clear2(l, p) # -> [2, 1, 3, 4, 1, 2]

Потестил на 5 примерах, оба варианта рабочии.