Особенности использования стандартных lock'ов для многопотока

Metrix

Client
Регистрация
03.01.2014
Сообщения
342
Благодарностей
272
Баллы
63
Данная переменная своя для каждого шаблона и не подходит для блокировки.
Для шаблонов-то ясно, что разные, речь о потоках одного шаблона была, но, думаю, что ты просто не дописал.
Там проблема больше, возвращаемый объект списка разный у шаблонов.
Так всё-таки, у шаблонов или потоков одного шаблона?
Для себя уже разобрался каким образом блокировать доступ к критической секции и каким объектом.
да он не понимает. я ему написал вон выше что локальные переменные не подходят для лока многопотока, в ответ только тролинг получил.
Твоё сообщение:
Phoenix78 сказал(а):
лочить локальную переменную не самая лучшая идея для работы в многопотоке
Формулируй чётче.

P.S. Тему поднял потому что комментарии к статье внесли путаницу.
Подытожу.
LaGir прав в своей статье!
То, что обсуждали в комментариях, про блокировку доступа к Зенносписку самим Зенносписком неверная информация и блокировка не работает, так делать нельзя.
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
потоки одного шаблона, совершенно ничем не отличаются от потоков других шаблонов. для каждого потока создается свое уникальное пространство, которое не пересекается никак с другими потоками, кроме специально выделенных мест, обозначенных static . вот эти статические места и можно залочить в многопотоке, так как они являются общими для всех потоков.
но я же не гуру c# , поэтому хз, как оно на самом деле *HAHA*
 

Metrix

Client
Регистрация
03.01.2014
Сообщения
342
Благодарностей
272
Баллы
63
но я же не гуру c#
Да понял, понял, не повторяйся :D
потоки одного шаблона, совершенно ничем не отличаются от потоков других шаблонов
Ну и что ты опять пишешь?
Статическим объектом, не вынесенным в общую библиотеку для шаблонов или объектом не инициализированным общей глобальной переменной, ты никак не залочишь доступ к критической секции другого шаблона.

Мне и так было понятно, что это не работает, вопрос почему, для себя разобрался, спасибо за помощь техподдержке Зеннолаба и ZSharp!
 

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
Лок почему-то не работает, может я что то неправильно делаю.
Делаю парсинг по объявлениям в 30 до 50 потоков
Ошибка возникает, когда удаляю дубли, пробовал два разных лока
C#:
lock(Locker.Ссылки){
// Привязать список к файлу
IZennoList list = project.Lists["Ссылки"];
list.Bind(@project.Variables["link_a"].Value);
var lst = project.Lists["Ссылки"];
var buff = lst.Distinct().ToList();
lst.Clear();
lst.AddRange(buff);
}
C#:
lock (SyncObjects.ListSyncer){
// Привязать список к файлу
IZennoList list = project.Lists["Ссылки"];
list.Bind(@project.Variables["link_a"].Value);
var lst = project.Lists["Ссылки"];
var buff = lst.Distinct().ToList();
lst.Clear();
lst.AddRange(buff);
}
1622361624252.png
Подскажите что делать надо
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
Лок почему-то не работает, может я что то неправильно делаю.
Делаю парсинг по объявлениям в 30 до 50 потоков
Ошибка возникает, когда удаляю дубли, пробовал два разных лока
C#:
lock(Locker.Ссылки){
// Привязать список к файлу
IZennoList list = project.Lists["Ссылки"];
list.Bind(@project.Variables["link_a"].Value);
var lst = project.Lists["Ссылки"];
var buff = lst.Distinct().ToList();
lst.Clear();
lst.AddRange(buff);
}
C#:
lock (SyncObjects.ListSyncer){
// Привязать список к файлу
IZennoList list = project.Lists["Ссылки"];
list.Bind(@project.Variables["link_a"].Value);
var lst = project.Lists["Ссылки"];
var buff = lst.Distinct().ToList();
lst.Clear();
lst.AddRange(buff);
}
Подскажите что делать надо
непонятно зачем lst нужна. у тебя же list уже есть. работай только с ней.
 
  • Спасибо
Реакции: Roman48

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
непонятно зачем lst нужна. у тебя же list уже есть. работай только с ней.
Я нашел сниппет для удаления дублей, и нашел сниппет для привязки к файлу, и сложил.
Теперь я понял, надо удалить
var lst = project.Lists["Ссылки"];
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
Я нашел сниппет для удаления дублей, и нашел сниппет для привязки к файлу, и сложил.
Теперь я понял, надо удалить
var lst = project.Lists["Ссылки"];
ну как то так. попробуй, будут ли ошибки.
C#:
lock (SyncObjects.ListSyncer){
// Привязать список к файлу
IZennoList list = project.Lists["Ссылки"];
list.Bind(@project.Variables["link_a"].Value);
var buff = list.Distinct().ToList();
list.Clear();
list.AddRange(buff);
}
 
  • Спасибо
Реакции: Roman48

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
ну как то так. попробуй, будут ли ошибки.
C#:
lock (SyncObjects.ListSyncer){
// Привязать список к файлу
IZennoList list = project.Lists["Ссылки"];
list.Bind(@project.Variables["link_a"].Value);
var buff = list.Distinct().ToList();
list.Clear();
list.AddRange(buff);
}
1622363339894.png
 

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
Другой сниппет нашел и нет ошибок, всегда помогает если испробывать несколько вариантов
C#:
lock(Locker.Ссылки){
// Привязать список к файлу
string path = project.Variables["link_a"].Value;
var lines = System.IO.File.ReadAllLines(path).ToList().Distinct().ToList();;
System.IO.File.WriteAllText(path, string.Join(Environment.NewLine, lines));
return 0;
}
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
что то не то. я попробовал щас в 100 потоков запустить. и нормально, ошибок нет.
Но я же их не сам нарисовал. Там одно временно три работы с этим списком, и все на много потоках
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
Но я же их не сам нарисовал. Там одно временно три работы с этим списком, и все на много потоках
у тебя там код ошибки, куда ведет ? а других местах обращение к списку идет через c# код ?
 

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
у тебя там код ошибки, куда ведет ? а других местах обращение к списку идет через c# код ?
Привязывал через списки так, может это и есть косяк? сейчас попробую все переделать
1622368957747.png
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
Именно в этом и была проблема, сейчас 50 потоков и не одной ошибки, я привязывал для того чтобы файл создать, теперь сделаю проверку на существования файла и все
 
  • Спасибо
Реакции: Koqpe

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
87
Благодарностей
7
Баллы
8
Можете подсказать в чем вопрос? Написал в ветке "вопросы новичков" - тема "отложенный запуск потоков" ?
 

bizzon

Client
Регистрация
08.09.2015
Сообщения
1 103
Благодарностей
132
Баллы
63
Для популярных типов внешних ресурсов в ZennoPoster предусмотрено три объекта синхронизации, которые в C#-коде указываются в круглых скобках после lock:
SyncObjects.ListSyncer - для списков
SyncObjects.TableSyncer - для таблиц
SyncObjects.InputSyncer - для буфера обмена
Если счетчик организован на файле, в который записывается каждый раз и читается в несколько потоков, то здесь как лочить?
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
Если счетчик организован на файле, в который записывается каждый раз и читается в несколько потоков, то здесь как лочить?
если работа только в одном шаблоне, но у него несколько потоков, то в общем коде создаешь общий объект и лочишь через него.
если нужна блокировка в нескольких проектах, то надо локер создавать в глобальных переменных и лочить его.
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 980
Благодарностей
4 433
Баллы
113
Подскажите, как сделать lock запроса с паузой?

Т. е. например шаблон работает в 100 потоков. Но в одном месте он дергает GET запрос одного сервиса. И нужно чтобы не раздражать сервис массированными запросами, дергать его не одновременно (по очереди) и с паузой.
Как это можно реализовать?
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
Подскажите, как сделать lock запроса с паузой?

Т. е. например шаблон работает в 100 потоков. Но в одном месте он дергает GET запрос одного сервиса. И нужно чтобы не раздражать сервис массированными запросами, дергать его не одновременно (по очереди) и с паузой.
Как это можно реализовать?
делаешь глобалку, заводишь туда дату. в c# в локе опрашиваешь глобалку на предмет выхода текущего времени за пределы таймаута. если не вышел, гуляешь дальше, если вышел за пределы, то ставишь в глобалку текущее время и уходишь по другой линии на запрос.
 
  • Спасибо
Реакции: Astraport

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 980
Благодарностей
4 433
Баллы
113
делаешь глобалку, заводишь туда дату. в c# в локе опрашиваешь глобалку на предмет выхода текущего времени за пределы таймаута. если не вышел, гуляешь дальше, если вышел за пределы, то ставишь в глобалку текущее время и уходишь по другой линии на запрос.
Спасибо, я хотел попроще.
Так не будет работать?
C#:
public static object SyncObject = new object();//в общем коде

//в проекте
lock (CommonCode.SyncObject){
    //собственно запрос
  var result = ZennoPoster.HttpGet(url, proxy, "UTF-8", ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.HeaderAndBody, timeout, cookies, userAgent, true, 5, AdditionalHeaders: new [] {"Referer: "+referer});
// Случайная пауза
Random rnd = new Random();
System.Threading.Thread.Sleep(rnd.Next(3, 18) * 1000);
}
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
Спасибо, я хотел попроще.
Так не будет работать?
C#:
public static object SyncObject = new object();//в общем коде

//в проекте
lock (CommonCode.SyncObject){
    //собственно запрос
  var result = ZennoPoster.HttpGet(url, proxy, "UTF-8", ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.HeaderAndBody, timeout, cookies, userAgent, true, 5, AdditionalHeaders: new [] {"Referer: "+referer});
// Случайная пауза
Random rnd = new Random();
System.Threading.Thread.Sleep(rnd.Next(3, 18) * 1000);
}
очень, очень плохая идея делать паузу в локе.... все шаблоны в этом месте замрут. 100 потоков будут ждать 100*(3,18 ) секунд = в максимуме последний в очереди шаблон исполнит запрос через 30 минут после в тыкания в лок. Тут многопоток превращается в однопоток по сути. 1 поток сделает столько же работы сколько 100 потоков с таким подходом.
 
  • Спасибо
Реакции: Astraport

bigloafer

Client
Регистрация
23.07.2020
Сообщения
243
Благодарностей
76
Баллы
28
Может попробовать дату класть в глобальную переменную?
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 980
Благодарностей
4 433
Баллы
113
  • Спасибо
Реакции: bigloafer

MaxLucky

Client
Регистрация
13.08.2017
Сообщения
186
Благодарностей
14
Баллы
18
Подскажите пожалуйста, как правильно залочить таблицу Exel, для добавления определённых строк

Через документацию составил:

IZennoTable table = project.Tables["test"];
//Лочим код изменения списка для многопотока
lock (SyncObjects.TableSyncer){
//Добавляем в список "Список 1" элемент со значением "строка"
table.AddRow("строка");
}

Но теперь вопрос, как прописать правильно разделители?
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 788
Благодарностей
2 454
Баллы
113
Подскажите пожалуйста, как правильно залочить таблицу Exel, для добавления определённых строк

Через документацию составил:

IZennoTable table = project.Tables["test"];
//Лочим код изменения списка для многопотока
lock (SyncObjects.TableSyncer){
//Добавляем в список "Список 1" элемент со значением "строка"
table.AddRow("строка");
}

Но теперь вопрос, как прописать правильно разделители?
C#:
table.AddRow(new[]{"строка1","строка2","строка3" });
 
  • Спасибо
Реакции: MaxLucky

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)