Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.84/32: Рейтинг темы: голосов - 32, средняя оценка - 4.84
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
.NET 4.x

Инструмент многопоточного программирования

22.09.2015, 12:18. Показов 6814. Ответов 74
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Программирование многопоточных приложений крайне непростое дело. Приходится обходить много подводных камней: учитывать гонки, взаимоблокировки и др. Специально для облегчения разработки программ создан инструмент, с помощью которого эти затруднения легко разрешимы. Инструмент представляет собой библиотеку классов, написанную на C# и включающую достаточное количество методов, позволяющих просто писать довольно сложные многопоточные приложения. Всем, кто интересуется созданием параллельных программ, эта библиотека классов способна в значительной степени облегчить написание кода.
Если будут какие-то вопросы, с удовольствием отвечу. А также буду весьма признателен за выявленные недостатки.

Программное обеспечение исполняющей среды представлено классами пространства имен – BindingAndServisParallel.
Полная документация, библиотека классов и пример хранятся: sites.google.com/site/algonauts/Home/fajly
в файлах DocCoreParallel.docx, BindingAndServisCoreParallel_dll.dll, main.cs.
Пример компилируется в среде Visual Studio 2010 Express на 64-х битной платформе. При компиляции проекта следует добавить ссылки:
BindingAndServisCoreParallel_dll, PresentationCore, PresentationFramework, System, System.Xaml, WindowsBase

Библиотеку классов BindingAndServisCoreParallel_dll версия сборки 0.0.0.1 можно использовать без ограничения в любых целях. 
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.09.2015, 12:18
Ответы с готовыми решениями:

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

Оптимальная реализация многопоточного приложения
Несколько простоватая проблема. Есть приложение, в нём пользователь запускает длительный процесс, и нужно, чтобы была возможность...

Ведение лога для многопоточного приложения
Всем привет! Задача состоит вот в чем: Создаются потоки, выполняющие какие то операции(сейчас это не важно). На главной форме есть...

74
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
28.09.2015, 12:53  [ТС]
Студворк — интернет-сервис помощи студентам
Psilon
чую-чую-чую! Вдохновлялись винапи?


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Пример выполняется на демонстрационном стенде, по той или иной кнопке. Этот пример 
// совпал с кнопкой Button3, значит здесь его пусковой механизм.
//Прежде всего нужно инициализировать главный класс библиотеки, т.е. запустить 
//исполнительную среду на выполнение
//MyCoreParallel=new  CoreParallel (MyWindow,0);
//Параметры конструктора:  MyWindow – любое окно приложения, закрытие которого остановит 
//все потоки. Следующий параметр – предполагаемое использование юнитов в программе, 
//параметр не очень важный, можно поставить 0, библиотека сама разберется.
 
 
public void Button3(object sender, EventArgs e)  
        { 
// юниты выполняют пользовательские  методы. Эти методы определим в любом классе, здесь 
//класс  KunstTable. Т.е этот класс просто амбар, где хранятся методы для юнитов. Создаем 
//экземпляр этого “амбара”. 
 
          KunstTable   kunstTable = new  KunstTable()
 
//  В амбаре есть два метода 
//public object exampleKunstTable(object arg, int myUnit)  
//public object FunctionViewMail(object param,int myUnit)
//Сигнатура методов определенная, первый аргумент – сжатая до типа объект 
//последовательность реальных аргументов. В самом методе этот аргумент следует разжать до 
//естественного вида. Например реально надо передать 2 аргумента int X, float[] F.
//object[] a = new object [2];  a[0]= (object) X; a[1]= (object)F;   object  arg = (object)a;
//Сжали до одного аргумента. В самом методе разжимаем.
//object[] a = new object [2];  a= (object[])arg;  int arg1= (int)a[0];  float[] arg2 = (float[])a[1];
//Второй целочисленный аргумент в методах  int myUnit, просто формальный параметр, его не 
//надо передавать, через него исполнительная среда подставит в метод номер юнита на котором 
//будет выполняться этот метод, в дальнейшем этот номер потребуется. Методы с такой 
//сигнатурой подпадают под стандартный тип  Func<object,int,object>. Дадим этим методам 
//мнемонические имена f2 и  f1.
           Func<object,int,object> f2  =  kunstTable.FunctionViewMail;
           Func<object,int,object> f1  = kunstTable.exampleKunstTable ;
 
//Юниты выполняются только в связке, т.е  должно быть не менее двух юнитов, поэтому 
//формально вводим юнит сервер, который ничего не делает, так все будет делать юнит – клиент.
         id11=  MyCoreParallel. CreateUnitAsServer(null,null,null, null, null,null);
//  А вот юнит – клиент как раз выполняет два метода, вначале f1, затем f2. Метод f1 –
//инициализирует графическую форму, если она не инициализирована. Далее работает метод f2 –
//он в эту форму вносит данные. Управление передается юниту серверу, который как мы помним 
//ничего не делает, т.е его работа пропускается. Управление снова передается методу f1, но 
//форма уже им инициализирована, так что метод пропускается. Реально работает метод f2, 
//выводт данные в форму.
       id12 = MyCoreParallel. CreateUnitAsClient(f1, null,f2,null, null,null);
//Здесь юниты связываются логически.
          MyCoreParallel.BindingUnitToUnit(id11, id12); 
//Запуск в работу связки юнитов.
          CoreParallel.StartAllUnits();         
 
        }
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
28.09.2015, 14:38
Цитата Сообщение от Dedoc Посмотреть сообщение
Строить на их основе программы, все одно, что строить дом на песке – толку не будет
Да ну?? Вы серьезно??? И что же, вы думаете, что ДО вас, никто не сделал ни одной толковой программы, используя "такое несовершенное" средство многопоточности???
Я не проф. кодер, но даже у меня есть несколько программ, работающих с многопоточностью. Думаю, у профессионалов их больше в разы. И теперь выходит, что все они бестолковые??? А вы всем открыли глаза, оказывается??
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
28.09.2015, 16:25
insite2012, не, ну раньше как-то и без JQuery сайты верстали, и норм было, а щас вот неудобно. Вопрос только в том, что автор сделал что-то полезное и юзабельное, либо не очень. Я пока склоняюсь к последнему варианту. Но может я просто слишком плохо разбираюсь в теме. Например, вот человек писал про то, как он RTOS разработал. У него я вот тоже не понял, зачем так делать двусвязный список, но учитывая общий уровень статьи, тоже не стал рано судить. И ниже он объясняет, почему именно так, а не иначе. Но там и код совсем другого уровня (посмотрел на гитхабе исходники). Так что по косвенным признакам вроде привязки к WPF (это вообще пушка), полное презрение к функции цитирования (выдают крайнюю степень велосипедостроения) можно делать какие-то выводы.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
28.09.2015, 17:58
Цитата Сообщение от Psilon Посмотреть сообщение
раньше как-то и без JQuery сайты верстали
Psilon, так я о том, что человек, зная, какого уровня достигли многопоточные инструменты в NET 4.0 (а в NET 4.5 и того больше), все же отзывается о них так, как будто построение программ на их основе - полная дребедень, и программы будут бестолковыми. Это перебор, ятд.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
28.09.2015, 19:09
insite2012, считаешь, что всё что можно уже напрограммировали и изобрели? Лично я предполагаю иначе. Так что новое, до чего еще никто до этого не догадался, вполне может появиться, мы только на пороге IT-эры, сейчас это по большей части искусство, а не ремесло, поставленное на поток. Есть куда расти. Соответственно возможны и самородки. Вопрос только в том, что мы имеем в данном случае. Так как считаем мы, полагаю, одинаково, можно дальше тему не развивать.
0
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
29.09.2015, 09:04  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
Да ну?? Вы серьезно??? И что же, вы думаете, что ДО вас, никто не сделал ни одной толковой программы, используя "такое несовершенное" средство многопоточности???
Естественно , есть многопочные приложения. Вопрос в цене разработки, степени надежности, удобстве разработки. Автор вовсе не отговаривает от использования тех или иных средств программирования, а знакомит с конкретной разработкой. Выбор за пользователем программных средств, нравится – применяйте, не нравится – есть другие средства.
0
0 / 0 / 0
Регистрация: 08.10.2015
Сообщений: 5
08.10.2015, 08:22
Можно ли с помощью этого пакета выполнить параллельно сортировку массива? Мне кажется что можно, но как это сделать конкретно. У меня 4-х ядерный процессор, а в документации сказано, что ядер должно быть не менее 8. Это существенно?
0
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
08.10.2015, 12:00  [ТС]
Цитата Сообщение от GarretShadow Посмотреть сообщение
У меня 4-х ядерный процессор, а в документации сказано, что ядер должно быть не менее 8. Это существенно?
Если пользоваться командами типа
public int CreateUnitAsServer (object F1, object Argument1, object F2, object Argument2, object F3, object Argument3)

количество свободных ядер под потоки (юниты) будет рано 4-3=1, т.е. одно физическое ядро. Одно ядро зарезервировано для ОС, два ядра зарезервированы за исполнительной системой. На одном ядре можно будет запустить программу, но проку от этого не будет.

К понедельнику добавлю команды типа
public int CreateUnitAsServerDirectCore (object F1, object Argument1, object F2, object Argument2, object F3, objectArgument3, int Core)

С помощью этих команд указывается номер ядра на котором будет выполняться поток, будут разрешены все ядра процессора, и тогда можно будет использовать 4-х ядерный процессор на полную мощность.

Вообще говоря, библиотека ориентирована на процессоры с количеством ядер не меньше 8.

Цитата Сообщение от GarretShadow Посмотреть сообщение
Можно ли с помощью этого пакета выполнить параллельно сортировку массива?
На выходных покумекаю, как это можно сделать.
0
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
19.10.2015, 10:15  [ТС]
Для выполнения программы надо скачать новую версию BindingAndServiceCoreParallel. Если затрудняетесь с настройками Visual Studio 2010 на 64-х битную платформу, в документации добавлен раздел Дополнительно, разъясняющий вопрос.
С программой будьте осторожней, не запускайте сразу большой массив, убедитесь, что процессор хорошо охлаждается или уменьшите скорость работы юнитов, - в комментариях программы указано как сделать.


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
using System;
using System.Windows;
using System.Threading;
using BindingAndServiceParallel;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Globalization;
namespace Primer1
{
    
    
    public  class ProgramSort : Application
{ public static CoreParallel myCoreParallel;
  public static    Ambar ambar;
  public static    int unit1, unit2;
  public static    ProgramSort programSort;   
  public static    TextBox textBox = new TextBox();   
  public static    int[] unSortedArray;
  public static    int[] sortedArray;
  public static    TableView  tableView1;
  public static    int processRun=0;      // признак запуска процесса
  public static    int processSorting;    // признак того что происходит процесс сортировки;
  public static    TextEditorCoreParallel textEditorCoreParallel;
  public static    TableView  tableView2;
  public static    int  unitManager;    
  public static    int countArray;         //   размер массива 
        
        [STAThread]
  public static void Main()
     {    programSort = new ProgramSort(); 
          programSort.Startup += ProgramStartup;
          programSort.Run();
 
     }
 
    static void ProgramStartup(object sender, StartupEventArgs e)
    { 
        myCoreParallel = new  CoreParallel(null,2000);     
        ambar = new Ambar();
        Func<object,int,object> f1  = ambar.unit1_F1; 
        Func<object,int,object> f2  = ambar.unit1_F2;   
         unit1=  myCoreParallel. CreateUnitAsServerDirectCore(f1,null,f2, null, null,null,0);
         unit2 = myCoreParallel. CreateUnitAsClientDirectCore(null, null,null,null, null,null,0);  
         myCoreParallel.BindingUnitToUnit(unit1, unit2);
         CoreParallel.StartAllUnits();       
    }
 
//...................................................................................................  
    
    
    
    
    }// class ProgrammSort
 
    public class Ambar
    {   public   TableBase  tableBase = null; // экземпляр экранной формы, инициализированный как null
//.....................................................................................................
        public object unit1_F1(object arg,int myUnit)  
     {  // метод должен открыть экранную форму. Необходимо сформировать письмо и прикркпить к нему метод открытия формы.
       if(tableBase!=null){ Thread.Sleep(1000); return  null;} // если форма уже открыта, пропускем выполнение метода
       CoreParallel.UserFormMail[] ufmArray = new CoreParallel.UserFormMail[1];  // создаем массив содержащий переменные типа UserFormMail
       CoreParallel.UserFormMail ufm  = new CoreParallel.UserFormMail();  // определяем переменную типа UserFormMail
       ufm.FromUnit=myUnit; // адрес отправителя
       ufm.ToUnit=0;        // адрес получателя письма
       ufm.FuncArgument=(object)myUnit; // формально, прикрепленный к письму метод должен содержать входной аргумент типа object,
                                        // просто соблюдение сигнатуры метода
       ufm.Func=   openForm; // прикрепили метод, выполняемый в основном потоке
       ufm.Metka= CoreParallel.GetNewMetka();  // признак того, что требуется  ответное письмо от юнита 0
       ufmArray[0]=ufm; // заполнили массив писем, применяется пакетный способ рассылки писем как наиболее быстрый
       CoreParallel.units[myUnit].unitMailSender. SetAndSendUserDataMailArray(ufmArray,0); // отправили массив писем в адрес юнита 0.
    
       CoreParallel.IdentificationMail returnMail =  null;  // создадим ссылку на письмо и инициализируем ее как null
  
           while(returnMail == null ) // выполнять чтение почтового ящика вплоть до поступления письма с меткой ufm.Metka
       {// ProgramSort.myCoreParallel.WaitMail(myUnit); // встали в ожидании ответного письма от юнита 0.  
           Thread.Sleep(1);
           returnMail =  CoreParallel.units[myUnit].unitMailSender.GetMailFromMetka (myUnit  ,ufm.Metka);  
       }
   // пришло ответное письмо, где в поле ReturnFromMetod находится ссылка на элемент RichTextBox, расположенный в главной форме 
 
        
          return returnMail.ReturnFromMetod ; // возвратили ссылку на элемент RichTextBox
     } //  public object unit1_F1(object arg,int myUnit) 
        
//...................................................................................................
 
     public  object openForm(object arg)
     {   
         if(tableBase!=null) return null; // дублируем проверку  метода unit1_F1, т.к. письмо доходит с задержкой, за это время метод
                                          // может выполниться дважды.       
         tableBase = new TableBase();     // открываем экранную форму
 //        tableBase.ShowGridLineOn();      // для отладки делаем видимыми линии сетки
// выведем  на форму название программы
        
         string strTextBlock1= "Многопоточная сортировка массива"; // текст заголовка
         string fontFamily="Verdana"; // шрифт
         int fontSize=27;   // размер шрифта
 // определим высоту и ширину текста        
         FormattedText F_strTextBlock1 = new FormattedText(strTextBlock1,  CultureInfo.GetCultureInfo("en-us"),  FlowDirection.LeftToRight,
         new Typeface(fontFamily), fontSize ,  Brushes.Black);
         TextBlock textBlock1 = new TextBlock();  // элемент отображения текста и ниже его настройки
         textBlock1.FontFamily              = new FontFamily(fontFamily);
         textBlock1.FontSize                = fontSize;
         textBlock1.Text=strTextBlock1;        
//добавлем строку к сетке высотой (int)F_strTextBlock1.Height*2 пикселей. Узел == 0, т.е это сама экранная форма    
         int usel0Row0 =   tableBase.   AddRowToUsel(0,(int)F_strTextBlock1.Height*2); 
         tableBase. AddColumnToRowFromUsel(0, 0,-1);  // добавляем колонку в строке 0 произвольной длины( параметр длины  = -1 ) 
// чтобы текст располагался по центру формы, добавим фиктивную колонку шириной равной ширине текста  
         tableBase. AddColumnToRowFromUsel(0, 0,(int)F_strTextBlock1.Width);      
         int uselFromTextBlock1 = tableBase. CreateUselFromObject((object)textBlock1);  // создадим содержащий узел и поместим в него элемент с надписью
         tableBase.SetHorizontalAlignment ((int) HorizontalAlignment.Center, uselFromTextBlock1); // для этого узла укажем выравнивание по центру
         tableBase.BindingCellToUsel(0,0, usel0Row0, uselFromTextBlock1); // поместим узел с надписью в ячейку [0,0] узла 0, т.е. верхней формы.
       
          int usel0Row1 = tableBase.AddRowToUsel(0,300);  // добаввим к осовной форме строку высотой 300 пикселей
  
          tableBase. AddColumnToRowFromUsel(0, usel0Row1,300); // добавим к этой строке 4 колонки
          tableBase. AddColumnToRowFromUsel(0, usel0Row1,20); // колонка  разделитель
          tableBase. AddColumnToRowFromUsel(0, usel0Row1,-1); // колонка для таблицы неопределенной длины ( -1)
          tableBase. AddColumnToRowFromUsel(0, usel0Row1,-1);
  
       
         ProgramSort. textEditorCoreParallel = new TextEditorCoreParallel(); // создадим элемент типа RichTextBox
         int uselFromTextEditor  = tableBase. CreateUselFromObject((object) ProgramSort.textEditorCoreParallel ); // разместим элемент в узле
         tableBase.BindingCellToUsel(0,0,usel0Row1 , uselFromTextEditor); // свяжем этот узел с ячейкой [0,1] главной формы
         
         
         ProgramSort. tableView1 = new TableView(); ProgramSort. tableView1.AddColumn("Исходный массив");// создадим элемент Таблица и определим колонку
         int uselFromtableView1   = tableBase. CreateUselFromObject((object)ProgramSort. tableView1 );  // разместим элемент в узле
         tableBase.BindingCellToUsel(0,2, usel0Row1, uselFromtableView1 );   // свяжем этот узел с ячейкой [2,1] главной формы
         
      
         
         ProgramSort.  tableView2 = new TableView(); ProgramSort.tableView2.AddColumn("Отсортированный массив"); // создадим элемент Таблица и определим колонку
         int uselFromtableView2   = tableBase. CreateUselFromObject((object)ProgramSort.tableView2 ); // разместим элемент в узле
         tableBase.BindingCellToUsel(0,3, usel0Row1, uselFromtableView2 ); // свяжем этот узел с ячейкой [3,1] главной формы
         tableBase.AddRowToUsel(0,20);
       
  // добавим снопку Монитор 
         int usel0Row3 = tableBase.AddRowToUsel(0,100);
         tableBase. AddColumnToRowFromUsel(0, usel0Row3,90 );
         Button monitor = new Button();    
         monitor   .Click += new  RoutedEventHandler (monitorEvent);
         monitor.Content="Монитор"; monitor.Height=20;  monitor.Width=70;
         int uselFromMonitor   = tableBase. CreateUselFromUIelement(monitor ); // разместим элемент в узле
         tableBase.BindingCellToUsel(0,0, usel0Row3, uselFromMonitor);
 // добавим поле ввода количества элементов сортировки. Элемент определен в глобальной области видимости переменных.  
         tableBase. AddColumnToRowFromUsel(0, usel0Row3,20 );
         tableBase. AddColumnToRowFromUsel(0, usel0Row3,90 );
 //        TextBox textBox = new TextBox();
        ProgramSort. textBox.Height=20; ProgramSort. textBox.Width=70;
        ProgramSort. textBox.Text="10";
         int uselFromTextBox   = tableBase. CreateUselFromUIelement(ProgramSort. textBox );
         tableBase.BindingCellToUsel(0,2, usel0Row3,uselFromTextBox );
  // добавим кнопку Старт       
         tableBase. AddColumnToRowFromUsel(0, usel0Row3,20 );
         tableBase. AddColumnToRowFromUsel(0, usel0Row3,90 );
         Button start = new Button();    
         start   .Click += new  RoutedEventHandler (startEvent);
         start.Content="Старт"; start.Height=20;  start.Width=70;
         int uselFromStart   = tableBase. CreateUselFromUIelement(start ); // разместим элемент в узле
         tableBase.BindingCellToUsel(0,4, usel0Row3, uselFromStart);
         
   // добавим кнопку Выход       
         tableBase. AddColumnToRowFromUsel(0, usel0Row3,20 );
         tableBase. AddColumnToRowFromUsel(0, usel0Row3,90 );
         Button exit = new Button();    
         exit   .Click += new  RoutedEventHandler (exitEvent);
         exit.Content="Выход"; exit.Height=20;  exit.Width=70;
         int uselFromExit   = tableBase. CreateUselFromUIelement(exit ); // разместим элемент в узле
         tableBase.BindingCellToUsel(0,6, usel0Row3, uselFromExit);      
         
         
         tableBase.MakeTable();           // рисуем форму непосредственно
         return (object) ProgramSort.textEditorCoreParallel ; // возвращаем ссылку на элемент RichTextBox для дальнейшего применения
     
     } //  public object openForm(object arg)
0
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
19.10.2015, 10:16  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//.............................................................................................................
 
          public object unit1_F2(object arg,int myUnit)  // стандартная сигнатура методов юнита
 
          { // метод выполняется после метода F1, выполняет диалог с пользователем
            // прочитаем значение, возвращаемое методом F1 
            // с помощью поткобезопасного варианта метода public   object   GetReturnToServer  (int unit,   int numberMetod) 
          
            int unit = myUnit;   // метод F2 исполняется тем же юнитом что и метод F1, поэтому myUnit у них одинаков
            int numberMetod=1;   // поскольку читаем значение метода F1, то параметр равен 1
              
           // поткобезопасный вариант принимает один аргумент типа object, запакуем входную последовательнсть аргументов
              
            object[] argument= new  object[2];
            argument[0]=(object)unit;
            argument[1]=(object)numberMetod;
            object input =(object)argument;
            
            Func<object,object> func =  ProgramSort.myCoreParallel.GetReturnToServerThread; // потокобезопасный вариант получения значения метода юнита
            TextEditorCoreParallel textEditorCoreParallel=null;
 error:     try  {      
             object ob= new object();
               
              ob=     CoreParallel.units[unit].unitRunMetod.RunMetodSync(func, input); // передаем метод и его аргумент  
             textEditorCoreParallel =  (  TextEditorCoreParallel) ob;
              
              
                     }
             catch(Exception e1)    {string  str=e1.ToString(); goto error; }
                        
              
  //   переменная   textEditorCoreParallel содержит ссылку на элемент RichTextBox, открытый в главной форме.
  // подготовим письмо и отошлем в адрес юнита 0 с методом заполнения формы addTextToRichTextBox(object arg) 
    
          CoreParallel.UserFormMail[] ufmArray = new CoreParallel.UserFormMail[1];  // создаем массив содержащий переменные типа UserFormMail
          CoreParallel.UserFormMail ufm  = new CoreParallel.UserFormMail();  // определяем переменную типа UserFormMail
          ufm.FromUnit=myUnit; // адрес отправителя
          ufm.ToUnit=0;        // адрес получателя письма
      
         
  // пакуем  аргументы 
          string text = "Будьте внимательны, программа может вывести\nпроцессор на близкую к максимальной\n"+
              "загрузку. Убедитесь в надежности системы охлаждения\n\n1. Введите количество элементов сортировки \n" + 
              "    в диапазоне от 1 до 10.000.000\n\n2. Нажмите кнопку Старт "; 
          object[] array = new  object[2]; array[0]= (object)text; array[1]= (object) textEditorCoreParallel; object arg1 =(object)array;
          ufm.FuncArgument = arg1; 
          ufm.Func=   addTextToRichTextBox; // прикрепили метод, выполняемый в основном потоке
          ufm.Metka= 0;  // признак того, что не требуется  ответное письмо от юнита 0
          ufmArray[0]=ufm; // заполнили массив писем, применяется пакетный способ рассылки писем как наиболее быстрый
          CoreParallel.units[myUnit].unitMailSender. SetAndSendUserDataMailArray(ufmArray,0); // отправили массив писем в адрес юнита 0. 
 
          while(ProgramSort.processRun==0) Thread.Sleep(1);  // ожидаем ввода данных
     
              int countArray= ProgramSort.countArray; 
              int core = ProgramSort.myCoreParallel.GetCountCore()-3;
    
  // сформируем независимый альянс юнитов выполняющих сортировку
            Sorting sorting = new Sorting();  // открыли класс обеспечивающий сортировку
            Func<object,int,object> f1  = sorting.managerSortingF1; // 
            Func<object,int,object> f2  = sorting.managerSortingF2; //
            Func<object,int,object> f3  = sorting.managerSortingF3; //
            ProgramSort.   unitManager=   ProgramSort.  myCoreParallel. CreateUnitAsServerDirectCore(f1,null,f2, null, f3,null,0);
    
 // Следующая команда позволяет задать скорость выполнения методов юнита, условно, в диапазоне 0-10000 (speedMax)
 // таким образом можно динамически регулировать скоростью исполнения отдельных частей кода
 // если процессор перегревается, присвойте значение 0 или 1             
              
              CoreParallel.units[ProgramSort.   unitManager].SpeedServer= CoreParallel.speedMax;
          
      
    // ВНИМАНИЕ! Важно 
//для следуещего цикла определим его переменные вне цикла. Это крайне рекомендуемое условие
// если в цикле есть потокобезопасное  обращение к методу, локальные переменные определяются вне цикла
// особенно осторожно относитесь к этому при асинхронных вызовах метода. Дело в том, что исполнение метода произойдет не мгновенно
// а переход к следующему оператору - сразу же по вызову метода. Когда произойдет реальное исполнение метода, программа может выйти
// из цикла. Все объявленные в цикле переменные потеряют область видимости и могут быть уничтожены сборщиком мусора. Когда реално произойдет
// выполнение метода, окажется что входной аргумент уже не существует. Если не уверены, что асинхронный  метод закончится в течении времени
// существования основного метода (т.е. метода в котором он был вызван), определите локальные переменные в глобальной области видимости 
// всей программы. В этом случае не допускайте использование этих переменных другими методами, только точечное использование.
      
              int[] parallelUnit = new  int[core];
 
              argument = new object[7];
     
               object arg2;
   
 // создадим рабочие юниты сортировки
      for(int i=0;i < core ; i++)
            { 
                argument[0]= null;  argument[1]= null; argument[2]=  null; argument[3]= null; argument[4]=  null;
                argument[5]=  null; argument[6]= (object)(1+i); 
                arg = (object)argument;
               
 error3:     try{                   
             
                parallelUnit[i]= (int)  CoreParallel.units[myUnit].unitRunMetod.RunMetodSync
                       (ProgramSort.myCoreParallel. CreateUnitAsClientDirectCoreThread, arg);           
                   }      
         catch(Exception e1)    {string  str=e1.ToString(); goto error3;}
 // Следующая команда позволяет задать скорость выполнения методов юнита, условно, в диапазоне 0-10000 (speedMax)
 // таким образом можно динамически регулировать скоростью исполнения отдельных частей кода
 // если процессор перегревается, присвойте значение 0 или 1          
          CoreParallel.units[parallelUnit[i]].SpeedClient= CoreParallel.speedMax;  
          ProgramSort.myCoreParallel.BindingUnitToUnit(ProgramSort.   unitManager,  parallelUnit[i]);  // свяжем рабочий юнит с менеджером          
         
      }   
 
      // упакуем аргументы для метода  managerSortingF1 юнит-сервера unitManager
     
      object[] argument1 = new  object[10];
      argument1[0]= (object) ProgramSort.unSortedArray; // исходный массив
      argument1[1]= (object) ProgramSort.sortedArray;   // отсортированный массив
      argument1[2] =(object) parallelUnit;   // список номеров серверов клиентов
      argument1[3]= (object)core; // количество ядер
  
      arg1 = (object)argument1;
  // сигнатура метода      int   SetArgumentToServer  (int unit,   int numMetod,   object Argument)  
  // требует первым аргументом - номер юнита, второй аргумент - номер метода, третий аргумент -  собственно сам аргумент метода юнита    
      object[] argument2 = new  object[3];
      argument2 [0]= (object) ProgramSort.unitManager; // номер юнита
      argument2 [1]= (object) 1;  // номер метода
      argument2 [2]= arg1;   // аргумент метода юнита
      arg2= (object)argument2;
 
      // установим для медода F1 юнита менеджера входные аргументы в потокобезопасном режиме
    
       CoreParallel.units[myUnit].musor.Add(new System.Collections.Generic.List<object>());  // сохраним входные аргументы
       int index=  CoreParallel.units[myUnit].musor.Count-1;
       CoreParallel.units[myUnit].musor[index].Add(arg2);
 
 error1:  try{
      CoreParallel.units[myUnit].unitRunMetod.RunMetodSyncSafe
                                           (ProgramSort.myCoreParallel.SetArgumentToServerThread , arg2, index);
     }
      catch(Exception e1)    {string  str=e1.ToString(); goto error1;}
 
      CoreParallel.StartAllUnits();  // запускаем юниты сортировки
   
 
          return null;
          }
//.............................................................................................................
  public void monitorEvent (object sender, EventArgs e){ ProgramSort.   myCoreParallel.RunMonitor(2);}
//.............................................................................................................
 
  public void exitEvent (object sender, EventArgs e){ CoreParallel.AbortAllUnits(); Application.Current.Shutdown();}
           
//.............................................................................................................
  public void startEvent(object sender, EventArgs e)
       {
 //  введем данные и очистим таблицы вывода
 
      if( ProgramSort.   processRun!=0) return;
     
   
      try{
            ProgramSort.   countArray = Int32.Parse(  ProgramSort.textBox.Text);
            }
         catch(Exception e1)    {string  str=e1.ToString();  return;}
         if(ProgramSort. countArray <1 || ProgramSort. countArray > 10000000)return;
         ProgramSort.unSortedArray = new int[ProgramSort. countArray];
         ProgramSort.sortedArray = new int[ProgramSort. countArray];
         Random random = new Random();
         ProgramSort. tableView1.ClearTable();
         ProgramSort. tableView2.ClearTable();
         for(int i=0; i< ProgramSort. countArray; i++){
             ProgramSort.unSortedArray[i]= random. Next ();
             ProgramSort.tableView1.AddRecord( ProgramSort.unSortedArray[i]);
         }      
     
      ProgramSort.   processRun=1;
      return;
 
       }
  
//.............................................................................................................
 
 public object addTextToRichTextBox(object arg)
 { // распакуем входной аргумент
            object[] array = (object[])arg;
            string text =(string)array[0]; 
            TextEditorCoreParallel textEditorCoreParallel = (TextEditorCoreParallel) array[1];      
    
            Paragraph myParagraph = new Paragraph(new Run(text));
            textEditorCoreParallel.flowDocument.Blocks.Add(myParagraph ); 
  
     return null;
 }
 
 public object addProgressToRichTextBox(object arg)
 { // распакуем входной аргумент
            object[] array = (object[])arg;
            string text =(string)array[0]; 
            TextEditorCoreParallel textEditorCoreParallel = (TextEditorCoreParallel) array[1];             
            textEditorCoreParallel.flowDocument.Blocks.Remove(textEditorCoreParallel.flowDocument.Blocks.LastBlock  );
        
            Paragraph myParagraph = new Paragraph(new Run(text));
            textEditorCoreParallel.flowDocument.Blocks.Add(myParagraph ); 
  
     return null;
 }
        
        
        
//.............................................................................................................
 
  
    }//class Ambar
0
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
19.10.2015, 10:18  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
//.............................................................................................................
//                                              Класс сортировки
//.............................................................................................................
 
public class Sorting
 {      int[] result; // массив результатов работы процессоров исполнителей 
        int[,] granicy; // массив вычисления диапазонов данных для процессов 
        int N;  // величина исходного массива
        int T;  // степень распараллеливания 
        int cikl=-1; // цикл сортировки
        int delta; // рабочая переменная
        int realProcess; // количество реальных процессов сортировки, выcчитываемая величина
        int[] unsortedArray; // массив подлежащий сортировке
        int[] sortedArray;   // отсортированный массив
        int[] myClients;     //  массив номеров рабочих юнитов
        float progress=0.0f;
 
    
    
    public object   managerSortingF1(object arg, int myUnit)   // метод управления сортировкой метод F1
       {  // распакуем входные аргументы
         if(ProgramSort. processSorting!=0) return null;
         ProgramSort.   processSorting=1;
         int cikl;
         object[] argument = (object[])arg;       
         unsortedArray = (int[])argument[0]; // исходный массив
         sortedArray   = (int[])argument[1]; //  отсортированный массив
         myClients = (int[]) argument[2]   ; //  массив номеров рабочих юнитов
   
         int core =(int)argument[3];               // число рабочих ядер
         result= new int[T];
         T= core;
   
         N = unsortedArray.GetLength(0);      // величина исходного массива
         result = new int[core];              // в этот массив потоки будут заносить результаты сортировки в каждом цикле
         granicy = new int[T,2];                // границы сортируемого массива (нижняя и верхняя )для каждого юнита
         
// назначим рабочим ядрам сортировки их методы
        for (int i=0;i<T;i++)
        { WorkCore wc = new WorkCore(); // методы должны принадлежать различным экземплярам класса
          Func<object,int,object> f1 = wc.coreSorting;
          ProgramSort.myCoreParallel.  SetMetodToClient  (myClients[i], 1,( object) f1, null) ;
        }
 
         int realProcess=1; // количество реальных процесов
         int  delta ;// = N-;  // величина сектора поиска каждого процесса
       
         for (cikl =0;cikl < N; cikl++) // основной цикл сортировки
         {
      
           delta= (N-cikl)/(T ); //величина сектора поиска каждого процесса
    
 // определим границы сортировки для процессов   
           realProcess=1; 
           granicy[0,0]= cikl;   granicy[0,1]= cikl + delta ; if( granicy[0,1] > N -1) {granicy[0,1]=N-1;  ProgramSort.  processRun=0;  return null;}
            
             for (int i=1;i < T; i++)
           {  granicy[i,0]= granicy[i-1,1] +1; if(granicy[i,0] > N-1) {ProgramSort.  processRun=0;  return null;}
              realProcess++;
              granicy[i,1]= granicy[i,0] + delta; if(granicy[i,1] > N-1)  granicy[i,1]= N-1;
              
           }
 
         }
 
        ProgramSort.  processRun=0;
        return null;
       }
//.............................................................................................................
 
    public object   managerSortingF2(object arg, int myUnit)   // метод управления сортировкой метод F2
    {// здесь распределяются задания рабочим юнитам сортировки
      
        if (++cikl <N)
       
       { 
            realProcess=1; // количество реальных процесов
            delta= (N-cikl)/(T ); //величина сектора сортировки каждого процесса
            granicy[0,0]= cikl;   granicy[0,1]= cikl + delta ; if( granicy[0,1] > N -1) {granicy[0,1]=N-1; }
     else       {
        for (int i=1;i < T; i++)
           {  granicy[i,0]= granicy[i-1,1] +1; if(granicy[i,0] > N-1) {break;}
              realProcess++;
              granicy[i,1]= granicy[i,0] + delta; if(granicy[i,1] > N-1)  granicy[i,1]= N-1;
              
           }
 
            }    
   
  //    Границы расчитаны, сформируем входные аргументы рабочих юнитов
        for(int i=1; i <=T; i++)
          { if( i <= realProcess) 
               { object[] ob = new object[3];
                 ob[0]= (object) unsortedArray; // соритруемый массив
                 ob[1]= granicy[i-1,0]; // нижняя граница сортировки
                 ob[2]= granicy[i-1,1]; // верхняя граница
                 object Argument = (object)ob;
                 ProgramSort.myCoreParallel.  SetArgumentToClient  (myClients[i-1], 1 , Argument);
 
               }
                 else {  ProgramSort.myCoreParallel.  SetArgumentToClient  (myClients[i-1], 1 , null);  }// если процесс не участвет в сортировке         
        }
    
    
            float tmp = ((float)cikl/(float)N) *100.0f;
            if(tmp <= progress+0.01f)  return null; // передали управление методу F3
            progress=tmp;
// выведем процент сортировки
            // подготовим письмо и отошлем в адрес юнита 0 с методом заполнения формы addProgressTextBox(object arg) 
          CoreParallel.UserFormMail[]  ufmArray = new CoreParallel.UserFormMail[1];  // создаем массив содержащий переменные типа UserFormMail
          CoreParallel.UserFormMail  ufm  = new CoreParallel.UserFormMail();  // определяем переменную типа UserFormMail
          ufm.FromUnit=myUnit; // адрес отправителя
          ufm.ToUnit=0;        // адрес получателя письма   
         
          // пакуем  аргументы 
          string text = "Выполнено " + tmp.ToString() +"%" + " задания"; 
          object[] array = new  object[2]; array[0]= (object)text; array[1]= (object)ProgramSort. textEditorCoreParallel; object arg1 =(object)array;
          ufm.FuncArgument = arg1; 
          ufm.Func=  ProgramSort.ambar.addProgressToRichTextBox; // прикрепили метод, выполняемый в основном потоке
        
          ufm.Metka=  0;  // признак того, что не требуется  ответное письмо от юнита 0
          ufmArray[0]=ufm; // заполнили массив писем, применяется пакетный способ рассылки писем как наиболее быстрый
          CoreParallel.units[myUnit].unitMailSender. SetAndSendUserDataMailArray(ufmArray,0); // отправили массив писем в адрес юнита 0.   
         
            
            
            return null; // передали управление методу F3
 
        }
        else { // сортировка закончена
        
   // подготовим письмо и отошлем в адрес юнита 0 с методом вывода результата
          CoreParallel.UserFormMail[] ufmArray = new CoreParallel.UserFormMail[1];  // создаем массив содержащий переменные типа UserFormMail
          CoreParallel.UserFormMail    ufm  = new CoreParallel.UserFormMail();  // определяем переменную типа UserFormMail
          ufm.FromUnit=myUnit; // адрес отправителя
          ufm.ToUnit=0;        // адрес получателя письма
    
          ufm.FuncArgument = null; 
          ufm.Func=    mailEnd; // прикрепили метод, выполняемый в основном потоке
          ufm.Metka= CoreParallel.GetNewMetka();  // признак того, что  требуется  ответное письмо от юнита 0
          ufmArray[0]=ufm; // заполнили массив писем, применяется пакетный способ рассылки писем как наиболее быстрый
          CoreParallel.units[myUnit].unitMailSender. SetAndSendUserDataMailArray(ufmArray,0); // отправили массив писем в адрес юнита 0. 
          ProgramSort.myCoreParallel.WaitMail(myUnit); // остановились в ожидании ответного письма, синхронизация
   
  // подготовим письмо и отошлем в адрес юнита 0 с методом заполнения формы addTextToRichTextBox(object arg) 
          ufmArray = new CoreParallel.UserFormMail[1];  // создаем массив содержащий переменные типа UserFormMail
          ufm  = new CoreParallel.UserFormMail();  // определяем переменную типа UserFormMail
          ufm.FromUnit=myUnit; // адрес отправителя
          ufm.ToUnit=0;        // адрес получателя письма   
         
  // пакуем  аргументы 
          string text = "Сортировка закончена\n"; 
          object[] array = new  object[2]; array[0]= (object)text; array[1]= (object)ProgramSort. textEditorCoreParallel; object arg1 =(object)array;
          ufm.FuncArgument = arg1; 
          ufm.Func=  ProgramSort.ambar. addTextToRichTextBox; // прикрепили метод, выполняемый в основном потоке
        
          ufm.Metka=  CoreParallel.GetNewMetka();   // признак того, что  требуется  ответное письмо от юнита 0
          ufmArray[0]=ufm; // заполнили массив писем, применяется пакетный способ рассылки писем как наиболее быстрый
          CoreParallel.units[myUnit].unitMailSender. SetAndSendUserDataMailArray(ufmArray,0); // отправили массив писем в адрес юнита 0.   
          ProgramSort.myCoreParallel.WaitMail(myUnit); // остановились в ожидании ответного письма, синхронизация
// уничтожим альянс юнитов сортировки
           CoreParallel.AbortUnit(ProgramSort.unitManager   );
           for(int i = 0; i < T; i++)  CoreParallel.AbortUnit( myClients[i]  );
           ProgramSort.   processSorting=0;
           ProgramSort.  processRun=0;
        }
    
        return null;
    }
//.............................................................................................................
    public object mailEnd(object ob){ for(int i=0; i < ProgramSort.unSortedArray.GetLength(0);  i++) 
                           ProgramSort.tableView2.AddRecord(sortedArray[i]);return null;}
   
//.............................................................................................................
 public object   managerSortingF3(object arg, int myUnit)   // метод управления сортировкой метод F3
    {// здесь обрабатываются результаты сортировки рабочих юнитов
     // прочитаем значения возврата методов рабочих юнитов
       object  ob = new object();
     
     for(int i=0; i< realProcess; i++)
         { 
           ob= ProgramSort.myCoreParallel. GetReturnToClient  (myClients[i],1); if(ob!=null) result[i]= (int)ob;
         }
  
     // найдем среди результатов максимальный 
        int max= unsortedArray   [result[0]]; int index=0;
        for(int i=0; i< realProcess; i++)
        {  if(   unsortedArray [result[i]]  <=  max) continue; max =  unsortedArray [result[i]];   index=i;  }
  
      if(unsortedArray[cikl] < max) { unsortedArray[result[index]]= unsortedArray[cikl]; } // поменяли значения найденного элемента 
        sortedArray[cikl]=max;
   
 
     return null;
    }
 
 
 
} //class Sorting
 
public class WorkCore
    {
      public object coreSorting(object arg, int myUnit)  // метод сортировки на одном ядре
      { if(arg==null) return  null;
        object[] ob= (object[])arg;
        int[] unsorted = (int[]) ob[0];  // сортируемый массив
        int gr1 =(int) ob[1]; int gr2= (int) ob[2];  // нижняя и верхняя границы сортировки
     
        // сортировка в отдельном потоке
        int max= unsorted[gr1]; int ret = gr1;
        for(int i=gr1 ; i<=gr2 ;i++) {if(unsorted[i] < max) continue; else {max = unsorted[i] ; ret=i;   } }
        return (object)ret ; // вернули индекс максимального элемента в сегменте массива
 
      }  
    }
 
}


Вся программа не размещается в одном посте, поэтому разбита на 3 части. Соедините их вместе или скачайте с сайта файл main.cs.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
19.10.2015, 13:02
Ну и ад По-моему на чистом С она меньше места бы заняла, с учетом распараллеливания
1
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
19.10.2015, 13:18  [ТС]
Дык, котлета собственно
C#
1
2
3
4
 // сортировка в отдельном потоке
        int max= unsorted[gr1]; int ret = gr1;
        for(int i=gr1 ; i<=gr2 ;i++) {if(unsorted[i] < max) continue; else {max = unsorted[i] ; ret=i;   } }
        return (object)ret ; // вернули индекс максимального элемента в сегменте массива
Остальное - гарнир к ней.
Кода много, но в принципе он простой.
0
 Аватар для Anklav
447 / 305 / 47
Регистрация: 23.01.2013
Сообщений: 661
19.10.2015, 21:51
Dedoc, зацени какой я код нашел, как круто получилось!

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;class E{static int A=4,B=10,M=1,D=5,Z=3,F=0;static int[]L={3,3};
static string a2(){int a=A,b=B,c=0,e=3,g=0,h,i,j,k,l,m,p,q=L.Length;var r=false;
var t=new int[10,20];t[M,D]=8;if(F!=1)goto X;for(int u=0;u<q;u++){c=L[u];int d=u
==0?Z:L[u-1];if(d==0||d==2){k=0;l=2;m=1;p=3;j=2;h=0;i=1;}else{k=1;l=3;m=0;p=2;j=
1;h=1;i=0;}if(u==0){if((Z!=k||c!=l)&&(Z!=l||c!=k))e=Z;else e=c;g=e==k?-1:1;A=A+g
*h;B=B+g*i;if(A<0||A>=10||B<0||B>=20){F=2;goto X;}if(t[A,B]==8)r=true;t[A,B]=5;}
if(u!=q-1||r)t[a,b]=c==m||c==p?c==m^d!=k?3:4:j;else t[a,b]=d==0||d==2?7:6;if(c==
0)b++;if(c==2)b--;if(c==1)a++;if(c==3)a--;}if(t[A,B]!=5){F=2;goto X;}if(r){t[a,b
]=c==0||c==2?7:6;F=3;for(h=0;h<10;h++)for(i=0;i<20;i++)if(t[h,i]==0)F=1;if(F==3)
goto X;var v=new Random();for(;;){M=v.Next(10);D=v.Next(20);if(t[M,D]==0){t[M,D]
=8;break;}}var w=new int[q+1];for(g=0;g<q;g++)w[g+1]=L[g];w[0]=e;L=w;}else{for(g
=q-2;g>=0;g--)L[g+1]=L[g];L[0]=e;}X:var R="";var x="\r\n";var s=new string('/',
20+4);R+=x+s+x;var y=" |-\\/O"=*";for(h=0;h<10;h++){R+="//";if(F==1)for(i=0;i<
20;i++)R+=y[t[h,i]].ToString();else{var z=F==2?"Game Over!":"  Win!!!  ";int C=
20/2;R+=new string(' ',C-5)+z+new string(' ',20-C-5);}R+="//";R+=x;}R+=s+
"   QuineSnake by KvanTTT for GoStash"+x;return R;}static void Main(){if(F!=0){
int a=(int)Console.ReadKey(true).Key;Z=a<37||a>40?L[0]:a-37;}if(F==0)F=1;var R=a2();var s=
"using System;class E{{static int {10}={8},{11}={9},{12}={6},{13}={7},{14}={4},{17}={16};static int[]{15}={5};static string a2(){{int a={10},b={11},c=0,e=3,g=0,h,i,j,k,l,m,p,q={15}.Length;var r=false;var t=new int[10,20];t[{12},{13}]=8;if({17}!=1)goto X;for(int u=0;u<q;u++){{c={15}[u];int d=u==0?{14}:{15}[u-1];if(d==0||d==2){{k=0;l=2;m=1;p=3;j=2;h=0;i=1;}}else{{k=1;l=3;m=0;p=2;j=1;h=1;i=0;}}if(u==0){{if(({14}!=k||c!=l)&&({14}!=l||c!=k))e={14};else e=c;g=e==k?-1:1;{10}={10}+g*h;{11}={11}+g*i;if({10}<0||{10}>=10||{11}<0||{11}>=20){{{17}=2;goto X;}}if(t[{10},{11}]==8)r=true;t[{10},{11}]=5;}}if(u!=q-1||r)t[a,b]=c==m||c==p?c==m^d!=k?3:4:j;else t[a,b]=d==0||d==2?7:6;if(c==0)b++;if(c==2)b--;if(c==1)a++;if(c==3)a--;}}if(t[{10},{11}]!=5){{{17}=2;goto X;}}if(r){{t[a,b]=c==0||c==2?7:6;{17}=3;for(h=0;h<10;h++)for(i=0;i<20;i++)if(t[h,i]==0){17}=1;if({17}==3)goto X;var v=new Random();for(;;){{{12}=v.Next(10);{13}=v.Next(20);if(t[{12},{13}]==0){{t[{12},{13}]=8;break;}}}}var w=new int[q+1];for(g=0;g<q;g++)w[g+1]={15}[g];w[0]=e;{15}=w;}}else{{for(g=q-2;g>=0;g--){15}[g+1]={15}[g];{15}[0]=e;}}X:var R={1}{1};var x={1}{2}r{2}n{1};var s=new string('/',20+4);R+=x+s+x;var y={1} |-{2}{2}/O{2}{1}=*{1};for(h=0;h<10;h++){{R+={1}//{1};if({17}==1)for(i=0;i<20;i++)R+=y[t[h,i]].ToString();else{{var z={17}==2?{1}Game Over!{1}:{1}  Win!!!  {1};int C=20/2;R+=new string(' ',C-5)+z+new string(' ',20-C-5);}}R+={1}//{1};R+=x;}}R+=s+{1}   QuineSnake by KvanTTT for GoStash{1}+x;return R;}}static void Main(){{if({17}!=0){{int a=(int)Console.ReadKey(true).Key;{14}=a<37||a>40?{15}[0]:a-37;}}if({17}==0){17}=1;var R=a2();var s={1}{0}{1};Console.Write(s,s,'{1}','{2}{2}',R,{14},{1}{{{1}+string.Join({1},{1},{15})+{1}}}{1},{12},{13},{10},{11},{1}A{1},{1}B{1},{1}M{1},{1}D{1},{1}Z{1},{1}L{1},{17},{1}F{1});}}}}{3}";Console.Write(s,s,'"','\\',R,Z,"{"+string.Join(",",L)+"}",M,D,A,B,"A","B","M","D","Z","L",F,"F");}}
Это квайн змейка.

Еще есть сравнимый шедевр на тему, называется ЩИ!!!Симулятор жестокости.

Извините.
0
0 / 0 / 0
Регистрация: 08.10.2015
Сообщений: 5
20.10.2015, 21:31
Это, похоже то, что надо, необходимо выполнить некоторую работу с максимальной эффективностью. Правильно ли понимаю, что любую задачу, заключающуюся в том чтобы выполнять действия над объектом имеющим линейные координаты независимо по отдельным участкам, можно свести к представленной реализации сортировки массива. Попробую взять из кода рациональное зерно и адаптировать под свою задачу, хотя у меня непрерывная многомерная система координат.
Концепция применения юнитов немного непривычна, на что посоветуете обратить внимание, от кода просто пестрит в глазах?
0
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
21.10.2015, 15:11  [ТС]
Концепция применения юнитов немного непривычна, на что посоветуете обратить внимание, от кода просто пестрит в глазах?
Кода много, уверяю все, что потребуется для применения – знание нескольких шаблонных приемов. Заучите их и все станет очень просто.
Прежде разберитесь, что такое юнит. Фактически юнит представляет поток, выполняющий в бесконечном цикле 3 метода. Эти методы и аргументы к ним можно задавать при создании юнита или добавлять/убирать в ходе выполнения программы. Минимум должно быть 2 юнита и один из них условно называется юнит-сервер, на рисунке изображен слева. Юнит-сервер начинает работу и выполняет подряд два метода F1 и F2 ( те, которые заданы при инициализации юнита). Обычно в методе F1 производится общая настройка системы, в методе F2 подготавливаются задания для юнит-клиента. Далее (см. блок-схему) управление передается юнит-клиенту. Как правило этот юнит производит основную работу, что-то вычисляет и т.д., т.е реализует задание юнит –сервера. Условно он может выполнять три различных метода. Это необязательно и больше для удобства. После того как юнит-клиент отработал, управление снова передается юнит-серверу. Как правило, с юнит сервером связаны несколько клиентов. Сервер ждет пока все они не отработают, т.е. не выполнят команду return. Когда все клиенты отработают, сервер собирает результаты их работы, можно путем чтения содержимого return (object) X или через общую переменную класса, как хотите. В методе F3 сервер , проанализировав данные, решает что делать дальше, можно закончить работу, можно продолжить цикл или выполнить другие действия. После этого управление снова- передается методу F1, который, скорее всего, должен пропустить свою работу (он выполняет подготовительные действия), управление переходит к методу F2 и цикл продолжается.
Юнит, сам по себе работает постоянно. Его можно либо удалить, либо загнать в паузу, можно указать низкую скорость работы.
Миниатюры
Инструмент многопоточного программирования  
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
21.10.2015, 16:28
Dedoc, вот вам кстати моя супер-библиотечка. Сортирует многопоточно, даже без SortingManager'ов.:

C#
1
2
3
4
5
6
7
public static class MySortingLib
{
    public static int[] ParallelSort(int[] arr)
    {
        return arr.AsParallel().OrderBy(x => x).ToArray();
    }
}
Конечно, кода не в пример больше, чем у вас, зато можно встроенными средствами обойтись
3
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
22.10.2015, 09:46  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
вот вам кстати моя супер-библиотечка

Шикарная библиотека!
ParallelEnumerable – класс
Потокобезопасность членов экземпляров не гарантируется.

Это дедушкины валенки, выбросите все это из головы и пользуйтесь современными средствами многопоточности.
0
 Аватар для Cupko
660 / 597 / 171
Регистрация: 17.07.2012
Сообщений: 1,685
Записей в блоге: 1
22.10.2015, 10:52
Цитата Сообщение от Dedoc Посмотреть сообщение
Это дедушкины валенки, выбросите все это из головы и пользуйтесь современными средствами многопоточности.
Просветите, пожалуйста, о "современных средствах многопоточности", не касаясь вашей библиотеки.
0
-39 / 2 / 1
Регистрация: 21.09.2015
Сообщений: 58
22.10.2015, 10:57  [ТС]
Цитата Сообщение от Cupko Посмотреть сообщение
Просветите, пожалуйста, о современных средствах многопоточности, не касаясь вашей библиотеки.
Понимаю, прозвучит нескромно, но имелась в виду именно эта библиотека. Возможно, есть что-то еще, погуглите.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.10.2015, 10:57

Нужен совет по архитектуре многопоточного приложения
Здравствуйте. Есть приложение WPF MVVM, которое обрабатывает файлы. Так как обработка файлов занимает время, то хотелось бы информировать...

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

Умножение матриц с использоанием многопоточного программирования
Нужно переделать однопоточное в многопоточное :( using System; using System.Collections.Generic; using System.Linq; using...

Время многопоточного выполнения функции
Этот код исполняется за 0.4 сек на моём компьюетере private void Foo() { for (int i = 0; i &lt; 100000000;...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru