Страницы

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

четверг, 16 мая 2019 г.

RAM info with dmidecode --type 17

На материнской плате ASUS V-PRO Z77 установлены 2х2 (Kingston и Corsair) планок оперативной памяти. Все четыре планки оперативной памяти нареканий в работе не вызывают. Работают исправно. Но, ниже представлен вывод результата запуска программы Dmidecode и в выводе меня интересуют следующие строки:
Error Information Handle: 0x0060 Error Information Handle: 0x0063
Что это значит и с чем связана такая информация?
$ sudo dmidecode --type 17 # dmidecode 2.12 # SMBIOS entry point at 0x000f04c0 SMBIOS 2.7 present.
Handle 0x005B, DMI type 17, 34 bytes Memory Device Array Handle: 0x005C Error Information Handle: 0x0060 Total Width: 64 bits Data Width: 64 bits Size: 4096 MB Form Factor: DIMM Set: None Locator: ChannelA-DIMM0 Bank Locator: BANK 0 Type: DDR3 Type Detail: Synchronous Speed: 1333 MHz Manufacturer: Kingston Serial Number: 9333B00B Asset Tag: 9876543210 Part Number: 99U5584-007.A00LF Rank: 1 Configured Clock Speed: 1333 MHz
Handle 0x005F, DMI type 17, 34 bytes Memory Device Array Handle: 0x005C Error Information Handle: No Error Total Width: 64 bits Data Width: 64 bits Size: 4096 MB Form Factor: DIMM Set: None Locator: ChannelA-DIMM1 Bank Locator: BANK 1 Type: DDR3 Type Detail: Synchronous Speed: 1333 MHz Manufacturer: 029E Serial Number: 00000000 Asset Tag: 9876543210 Part Number: CMZ8GX3M2A1600C9 Rank: 2 Configured Clock Speed: 1333 MHz
Handle 0x0062, DMI type 17, 34 bytes Memory Device Array Handle: 0x005C Error Information Handle: 0x0063 Total Width: 64 bits Data Width: 64 bits Size: 4096 MB Form Factor: DIMM Set: None Locator: ChannelB-DIMM0 Bank Locator: BANK 2 Type: DDR3 Type Detail: Synchronous Speed: 1333 MHz Manufacturer: Kingston Serial Number: 1D10C373 Asset Tag: 9876543210 Part Number: 99U5584-018.A00LF Rank: 1 Configured Clock Speed: 1333 MHz
Handle 0x0065, DMI type 17, 34 bytes Memory Device Array Handle: 0x005C Error Information Handle: No Error Total Width: 64 bits Data Width: 64 bits Size: 4096 MB Form Factor: DIMM Set: None Locator: ChannelB-DIMM1 Bank Locator: BANK 3 Type: DDR3 Type Detail: Synchronous Speed: 1333 MHz Manufacturer: 029E Serial Number: 00000000 Asset Tag: 9876543210 Part Number: CMZ8GX3M2A1600C9 Rank: 2 Configured Clock Speed: 1333 MHz
UPD
$ sudo dmidecode --type 18 # dmidecode 2.12 # SMBIOS entry point at 0x000f04c0 SMBIOS 2.7 present.
Handle 0x005D, DMI type 18, 23 bytes 32-bit Memory Error Information Type: OK Granularity: Unknown Operation: Unknown Vendor Syndrome: Unknown Memory Array Address: Unknown Device Address: Unknown Resolution: Unknown
Handle 0x0060, DMI type 18, 23 bytes 32-bit Memory Error Information Type: OK Granularity: Unknown Operation: Unknown Vendor Syndrome: Unknown Memory Array Address: Unknown Device Address: Unknown Resolution: Unknown
Handle 0x0063, DMI type 18, 23 bytes 32-bit Memory Error Information Type: OK Granularity: Unknown Operation: Unknown Vendor Syndrome: Unknown Memory Array Address: Unknown Device Address: Unknown Resolution: Unknown
Handle 0x0066, DMI type 18, 23 bytes 32-bit Memory Error Information Type: OK Granularity: Unknown Operation: Unknown Vendor Syndrome: Unknown Memory Array Address: Unknown Device Address: Unknown Resolution: Unknown


Ответ

Это значит, что информация об ошибках находится в других записях с номерами 0x0060 и 0x0063 соответственно.
Дабы узнать, что за ними скрывается dmidecode следует запустить без параметров и просмотреть вывод. Номера handel'ов указываются в заголовках в выводе следующим образом:
Handle 0x005B, DMI type 17, 34 bytes Memory Device
Вероятно их тип будет 18 (32-bit Memory Error Information) или 33 (64-bit Memory Error Information).
По всей видимости само наличие значения в поле Error Information Handle покуда в структуре на которую он ссылается значение Type: OK. Как именно представляются данные определяется реализацией.

C# Создание экземпляра потомка по типу, определенному в базовом классе

Есть базовый класс
public abstract class Session { public abstract SessionType SessionType { get; } }
И есть куча его наследников, возвращающих нужный тип SessionType.
Каждому типу строго соответствует один наследник.
Вопрос:
Как создать экземпляр нужного потомка зная тип.
ПС. Понятно, что можно сделать метод по свичу создающий потомков. Но тогда при каждом создании нового типа нужно будет добавлять новую инициализацию объекта. Можно ли это сделать более простым способом?


Ответ

Большое спасибо за ответы. Оба ответа мне помогли.
Решил задачу немного другим способом, отличным от обоих предложенных.
Точнее, соединил их в одно решение.
Идея:
Для каждого класса-потомка устанавливается атрибут.
Потом сканируем потомков и определяем по атрибуту нужный тип
Создаем экземпляр.
Реализация:
using System; using System.Linq; using System.Reflection;
namespace TestAttrib { public enum SessionType { One , Two } public abstract class Session { public abstract SessionType SessionType { get; }
public static Session construct(SessionType sessionType) { Type typeSession = typeof(Session); Type type = Assembly.GetAssembly(typeSession).GetTypes().SingleOrDefault(t => t.IsSubclassOf(typeSession) && (t.GetCustomAttribute(typeof(SessionTypeAttribute)) as SessionTypeAttribute).SessionType == sessionType );
if (type != null) { return (Session)Activator.CreateInstance(type); } return null; } }
[SessionType(SessionType.One)] public class Session_One : Session { public override SessionType SessionType => SessionType.One; }
[SessionType(SessionType.Two)] public class Session_Two : Session { public override SessionType SessionType => SessionType.Two; }
[AttributeUsage(AttributeTargets.Class)] public class SessionTypeAttribute : Attribute { public SessionTypeAttribute(SessionType sessionType) { SessionType = sessionType; } public SessionType SessionType { get; } } class Program { static void Main(string[] args) { Console.WriteLine(Session.construct(SessionType.One).ToString()); //Выведет TestAttrib.Session_One Console.WriteLine(Session.construct(SessionType.Two).ToString()); //Выведет TestAttrib.Session_Two Console.ReadLine(); } } }

Как лучше всего проверить, что окно существует?

Допустим, я пишу функцию, которая по значению дескриптора должна вернуть логическое значение, существует ли окно с таким дескриптором. Я представляю огромное количество реализаций - от перебора всех окон через GetProcesses или EnumWindow и до вызова какой-нибудь функции, принимающей hwnd, и возвращающую результат. А может я все усложняю, а такая функция входит в user32. В общем, как будет лучше и быстрее?


Ответ

Есть WinApi функция IsWindow, но как пишут в этом ответе хендл может переназначаться => если вы пасете определенное окно и хотите проверить его существование, то окно может быть уже закрыто, но хендл с таким же номером был создан для другого окна.
[DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWindow(IntPtr hWnd);
Получается, что имеет смысл воспользоваться вот этой функцией, если у окна есть специфическое название GetWindowText , она вернет Caption окна и можно удостоверится, что именно желаемое окно живо.
Через WinApi я думаю, что быстрее.
Что лучше?
Все зависит от того, как часто вы это собираетесь делать. Если не часто, то я бы не заморачивался и выполнял итерацию по процессам.

Android Studio засунуть сайт в приложение

Всем привет, подскажите как засунуть сайт в приложение ? к примеру как тут http://www.appsgeyser.com/create-url-app/ где об этом почитать можно ? или пример, курс


Ответ

Если вы имеете в виду отображение какого-то сайта в вашем приложении, то для этого есть элемент WebView
1) В разметке добавляете:

2) В коде для загрузки требуемого сайта используете следующее:
WebView webView = findViewById(R.id.web_view); webView.loadUrl("https://ru.stackoverflow.com/");

Как лучше сделать анимацию нескольких монеток, которые уменьшаясь, летят в одну точку?

Есть изображение кучки золота, есть анимированный открывающийся сундук. При нажатии на кучку, она должна превратиться в горсть монеток и полететь в сундук. Каким образом лучше сделать анимацию этих монеток? Каждую загрузить как ImageView и отдельно анимировать?
Ответ на комментарий:
Я до сих пор новичок, и использую только ConstraintLayout, после уроков так повелось. Мне надо переделать все на Relative? Мне не нужно наследовать ваш класс от AppCompatActivity, только провести нужные импорты? Параметр paddings в R.dimen.paddings подсвечен красным. Вот с этой строчкой запутался. ((тип parent startView)startView.getParent).removeView (startView);
Изменил ее так:
((ImageView)startView.getParent()).removeView(startView);
но теперь removeView() красный.
При имплементации класса, мой главный класс требует обьявить абстрактным или имплементировать абстрактный метод AnimationEnd(int)


Ответ

Использую для подобных целей (в моем случае - "летят" очки) класс ниже.
Использование: где надо для каждой кучки создавайте его экземпляр и передавайте контекст, RelativeLayout (да, надо чтобы корневой View activity был RelativeLayout. Можно FrameLayout), изображение, с которого начинается движение (ваша кучка, где бы она не была), изображение сундука (куда полетят деньги)), количество, которое "долетит" (сумма денег).
public class AnimateScore { private static final int ANIMATION_DURATION = 400;
private View targetView; private int offset, number; private AnimationEnd animationEnd; private ImageView img; private RelativeLayout container;
interface AnimationEnd { void animationEnd(int number); }
AnimateScore(Context ctx, RelativeLayout container, View startView, View targetView, int number) { animationEnd = (AnimationEnd) ctx; this.number = number;
int dimens = (int) ctx.getResources().getDimension(R.dimen.paddings); offset = (int) (-24 * ctx.getResources().getDisplayMetrics().density);
this.container = container;
this.targetView = targetView;
img = new ImageView(ctx); int[] coords = {getRelativeLeft(startView), getRelativeTop(startView)}; String str = "+" + String.valueOf(number); img.setImageResourse(R.drawable.my_img) img.setPadding(dimens, dimens, dimens, dimens); img.setX(coords[0] + dimens * 2); img.setY(coords[1]);
((тип parent startView)startView.getParent).removeView (startView);
container.addView(img); img.postDelayed(new Runnable() { @Override public void run() { drawAnimation(img); } }, 10); }
private void drawAnimation(View v1) { v1.clearAnimation(); ScaleAnimation animation = new ScaleAnimation (1, 0,1,0); animation.setDuration(ANIMATION_DURATION + 100); animation.setFillAfter(true); v1.setAnimation(animation); v1.startAnimation(animation); v1.animate().translationX(getRelativeLeft(targetView)) .translationY(getRelativeTop(targetView) + offset).setDuration(ANIMATION_DURATION) .setInterpolator(new DecelerateInterpolator()).setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {
}
@Override public void onAnimationEnd(Animator animation) { container.removeView(img); animationEnd.animationEnd(number); }
@Override public void onAnimationCancel(Animator animation) {
}
@Override public void onAnimationRepeat(Animator animation) {
} });
}
private int getRelativeLeft(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getLeft(); else return myView.getLeft() + getRelativeLeft((View) myView.getParent()); }
private int getRelativeTop(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getTop(); else return myView.getTop() + getRelativeTop((View) myView.getParent()); } }
offset - для корректной работы (не знаю откуда смещение, но так)
dimens*2 - чтобы учитывать два родительских padding
в классе-приёмнике не забудьте implements AnimateScore.AnimationEnd
немного адаптировал класс под ответ, если что-то не работает или есть вопрос - пишите в комментариях ;)
Раз:


Два: нет, просто в нужный момент вызывайте экземпляр: new AnimateScore (YourActivity.this, findViewById(R.id.globalcont),your_coin_pile_img,your_chest_img, 100)
Три: это отступы, прописанные у меня в dimen. Это можно удалить либо подвести туда курсор, нажать alt+enter и ввести значение (обычно 5-10-15dp). Либо прописать в dimen в ручную.
Четвере: "тип parent" - тип контейнера в котором лежит ваша "кучка золота" (LinearLayout, FrameLayout, ConstrainLayout и т.д.)
Пять: имплементируйте :) (alt+enter, когда курсор на красном). Необязательная часть, можете удалить вместе с interface. Нужна, для того, чтобы отслеживать, когда анимация "дошла" и, например, только тогда добавлять монеты в сундук.

Linq удалить диапазон по id

Как написать запрос удаления диапазона по списку id, без создания сущностей которые требуются в RemoveRange?


Ответ

Решил вопрос таким образом (через фейковые объекты):
public async Task DeleteUsersByIdAsync(IEnumerable id_users) { using (REMOTE_OFFICE_3Entities db = new REMOTE_OFFICE_3Entities()) { IEnumerable delete_users = id_users .Select(selector: id => new User { id = id }) .Select(selector: read => db.Users.Attach(entity: read));
db.Users.RemoveRange(entities: delete_users); await db.SaveChangesAsync(); } }

Что происходит с памятью при вызове exec() на уровне ядра?

Вопрос теоретический. fork() делает копию процесса. Известно, что родительский процесс имеет собственное адресное пространство. Дочерний процесс, фактически, до какого-то момента может работать с адресным пространством своего родителя. Этот момент - запись в адресное пространство. Таким образом дочерний процесс в режиме "только чтение" может в полной мере руководствоваться родительским адресным пространством. Если производится запись, то адресное пространство копируется (copy-on-write [COW]). Возникает несколько вопросов:
Что будет со скопированным адресным пространством, если будет вызван exec()? Если после fork() вызвать exec(), то новый исполняемый код создает свое собственное адресное пространство? Что будет с таблицей страниц дочернего процесса после вызова exec()?


Ответ

Рассматривать что происходит с памятью при вызове exec() в отрыве от остальной подсистемой управления пямятью — неполноценно и описать этот процесс можно только в общих словах. А по всей данной подсистеме можно написать целую книгу (и несколько уже написаны), но я всё же попытаюсь выделить основные моменты.
Немного о структурах связанных с управлением памятью процесса
Кратко опишу назначение основных структур связанных с управлением памятью процесса.
Структуры связанные с управлением виртуальным АП.
task_struct — дескриптор процесса mm_struct — адресное пространство процесса vm_area_struct — отдельный сегмент памяти процесса со своим набором атрибутов (rwx), можно думать о нём как о неком регионе отображённом в память mmap ()'ом: он может быть и частью файла (исполняемого или обычного) и простым анонимным участком памяти. Список можно посмотреть, например в /proc//maps
Структуры связанные с трансляцией адресов и физической памятью:
pgd_t и pmd_t (а также p4d и pud) — системно-зависимые типы для записей в глобальной директории страниц (Page Global Directory) и промежуточной директории страниц (Page Middle Directory), если таковая есть (на простом x86 таковой нет). p4d и pud — это дополнительные типы в новых ядрах для пятиуровневой и четырёхуровневой адресации. pte_t — системно-зависимый тип Записи в таблице страниц (Page Table Entries). На x86 это, как и pgd_t 32-битный тип с аналогичным названием struct page — системно-независимая структура представляющая страницу физической памяти. Все они постоянно хранятся в памяти в массиве mem_map
Если кратко, то эти структуры взаимосвязаны следующим образом:
task_struct.mm ссылается на mm_struct, связанный с процессом. На один mm_struct может ссылаться несколько task_struct (так в частности реализованы потоки) mm_struct.mmap в свою очередь ссылается на двусвязный список vm_area_struct, связанных с процессом. mm_struct.pgd хранит адрес глобальной директории страниц pgd_t связанной с процессом. На x86 он фактически загружается в CR3 при смене контекста. vm_area_struct.mm — указатель на mm_struct к которому принадлежит данный сегмент. vm_area_struct.next и vm_area_struct.prev — указатели на предыдущий и следующий элемент в двусвязном списке. Для pte_t и pgd_t можно получить соответствующую структуру struct page с помощью макросов и pte_page() и pgd_page() соответственно.
Немного о том, как работает COW
При создании нового процесса fork ()'ом цикл проходится по всем связанным с ним vm_area_struct и помечает все доступные на запись страницы (pte_t), доступными только на чтение. А в соответствующей struct page увеличивается счётчик ссылок на страницу.
Когда процесс пытается записать в такую страницу, происходит прерывание, далее обработчик (спустившись на несколько функций по стеку вызовов) определяет, что хотя прерывание произошло на странице на которой запрещена запись (согласно pte_t), эта страница относится к сегменту, в котором она разрешена (согласно vm_area_struct). Таким образом определяется, что это одна из COW-страниц и происходит копирование. После чего уменьшается счётчик ссылок исходной страницы (в struct page) и, если он достиг нуля, снова разрешается запись в неё.
Что происходит с адресным пространством при execve()
Сначала exec() создаёт новое АП (mm_struct) частично его инициализирует (например создаёт стек), А потом пробует подсунуть файл поочерёдно каждому из модулей поддержки форматов (например ELF) пока один из них не сможет его загрузить. Модуль в свою очередь сначала проводит частичную проверку формата и также частичную инициализацию АП, а затем, когда убедится, что формат выбран правильно и скорей всего удастся загрузить данный файл, происходит подмена старого АП новым и последующая подчистка старого. В частности она включает:
Уменьшение количества пользователей АП (mm_struct.users), если оно достигло нуля, то:
В цикле обходятся все vm_area_struct и для каждой происходит рекурсивная итерация по каталогу страниц в результате счётчики ссылок всех ассоциированных страниц (struct page) уменьшаются аналогично тому как это было описано для COW. После этого в другом цикле обходятся все vm_area_struct и записываются несохранённые данные из грязных страниц mmap-файлов. Уменьшается количество ссылок на АП (mm_struct.count) и если оно достигло нуля (кроме процессов структура может использоваться другими подсистемами ядра), то она полностью удаляется
В случае успешного завершения модуль формата продолжит инициализацию АП, а затем произойдёт передача управления процессу.
Стоит заметить, что операция подмены АП(вызов flush_old_exec()) — это точка невозвращения, т.е. после оной exec () уже не сможет вернуть одну из документированных ошибок; и в случае сбоя весь процесс будет аварийно завершён по сигналу, например, SIGSEGV
Односложные ответы на конкретные вопросы
Что будет со скопированным адресным пространством, если будет вызван exec()?
Оно будет замещено другим, созданным exec ()
Если после fork() вызвать exec(), то новый исполняемый код создает свое собственное адресное пространство?
Да.
Что будет с таблицей страниц дочернего процесса после вызова exec()?
Она также будет замещена новой. Страницы не используемые другими будут добавлены в список свободных.
Дальнейшее чтение:
Understanding The Linux Virtual Memory Manager — Книга описывает довольно старое ядро, но отличия в основном косметические, а основные принципы не изменились.