Try English version of Quizful



Раздаем бесплатные Q! подробности в группе Quizful.Alpha-test
Топ контрибуторов
loading
loading
Знаете ли Вы, что

Лучшие IT работодатели регулярно просматривают рейтинги и профили пользователей в поисках кандидатов. Для корректного отображения ваших данных рекомендуем заполнить ваш профиль и добавить информацию о вас и вашей профессии.

Лента обновлений
ссылка 12:31:40
Комментарий от log4456602:
Я так понял для варианта :
String a1 = "Test";
String...
ссылка 12:05:43
Добавлен вопрос в тест Базы данных (теория)
ссылка 11:22:41
Комментарий от log4456602:
Действительно!)))
ссылка 00:08:51
Добавлен вопрос в тест XML
ссылка 00:06:23
Добавлен вопрос в тест XML
Статистика

Тестов: 153, вопросов: 8597. Пройдено: 417953 / 2039327.

Цепляем Java Thread на нужное нам процессорное ядро

head tail Статья
категория
Java
дата21.04.2010
авторbu_ma_ga
голосов20

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

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

Многозадачность в Java так же ограничена средой JVM, но тем не менее существует возможность привязать конкретный Java thread на любое процессорное ядро (или на 2 или на 3 в произвольном сочетании).

Все что нам нужно из сторонних библиотек это JNA (Java Native Access).

На главной странице проекта (https://jna.dev.java.net) читаем –

JNA позволяет программам на Java получать удобный и простой доступ к внешним системным библиотекам (Windows dll), при этом писать нативный (с++) код, а так же пользоваться JNI нет необходимости. Доступ к dll осуществляется динамически, не требуется предварительно генерировать промежуточный код.

Разработчику нужно описать интерфейс (Java) описывающий нужные функции целевой библиотеки (dll).

1. Создаем класс KernelThreadSupport (естественно назвать можно как угодно)


package org.guap;

// импортируем нужные классы из библиотеки jna
// их можно скачать с сайта https://jna.dev.java.net
import com.sun.jna.Native;
import com.sun.jna.Library;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;

public class KernelThreadSupport {

// создаем статическую переменную нашего интерфейса
// при этом мы получим интерфейсный класс позволяющий вызвать
// метод SetThreadAffinityMask из dll kernel32

public static ThreadSupport threadSupport =
(ThreadSupport) Native.loadLibrary("kernel32", ThreadSupport.class);

    // Kernel32 это класс взятый из архива, я просто присоеденил к проекту examples.zip,
    // архив этот скачал с того же сайта
    // внутри class файлы уже описанных методов библиотеки kernel32
    //(но не всех, как раз SetThreadAffinityMask там не оказалось,
    // потому и пришлось его    определять самому)

    public static Kernel32 kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

    // Тут же определяем через интерфейс нужную нам библиотечную функцию

    public interface ThreadSupport extends Library {
        int SetThreadAffinityMask(Pointer hThread, int dwThreadAffinityMask);
    }
}

 

Теперь для решения нашей основной задачи нужно просто сделать следующий вызов в потоке который мы хотим повесить на нужное нам ядр:


// Маска определяет на какие ядра мы вешаем наш поток
// Внутри важно двоичное представление числа,
// и так как 0x00000007 в двоичной системе это 00000111
// значит мы хотим повесить выполнение нашего потока на три ядра
// по порядку младших битов.
// К примеру если бы мы хотели задействовать первое и третье ядро
// (нумерация условна, зависит от системы) нужно было бы запихать в качестве маски 00000101 – те 0x00000005 

int coreMask = 0x00000007;
int flag =
KernelThreadSupport.threadSupport.SetThreadAffinityMask(
           // вызываем указатель дескриптора текущего потока
           KernelThreadSupport.kernel32.GetCurrentThread().getPointer(),
           // устанавливаем нужную маску
           coreMask);
В переменной flag мы увидим предыдущее значение маски.

Вот собственно и все. Результаты легко можно увидеть в диспетчере задач.

К примеру в моем случае при 3 разных вариантах я видел следующее –

Для маски 0x00000002 (00000010)
Для маски 0x00000002

Для маски 0x00000007 (00000111)
Для маски 0x000000007

Для маски 0x00000006 (00000110)
Для маски 0x0000006

 

Если Вам понравилась статья, проголосуйте за нее

Голосов: 20  loading...
art   yohan   admin   elankaa   Artem   lightstorm   DDRON   ldkfa   RazorJack   JurasicSTR   Donskoy   romyli4ka   Sergo   endryha   sheff4ik   ZsergUYA   bonitamystar   botsms   Riddler   SamTan