
Oleg
09.07.2017
17:08:27
Типа в /etc/dub.json

Denis
09.07.2017
17:08:29
SailfishOS нуждается в софте и она завязана на Qt
Может это шанс
сам формат dub.json вроде не позволяет такого

Google

Pavel
09.07.2017
17:10:10
и почему num == 2
Почему там 2, я могу предположить, в случае если переменная шарится в тред. Когда мы доходим до конца первой итерации, создав тред, то num == 1 очищается как локальная переменная. На второй итерации по этому же адресу инициализируется новая num со значением 2, и тут приходит время первого треда прочитать переменную по этому адресу, и он читает двойку. Со вторым тредом то же выходит.
import std.stdio, core.thread;
int i = 1;
void main(string[] args)
{
while (i <=5 ) {
Thread.sleep(1.msecs);
shared immutable int num = i++;
writefln(
"num = %d (@%s), i = %d",
num, &num, i
);
new Thread({
writefln(
"thread num = %d (@%s)",
num, &num
);
}).start();
}
}Попробуйте вместо 1.msecs вписать 10.msecs, увидите забавные результаты :) Если подождать подольше, то все начинает работать как ожидается.

Denis
09.07.2017
17:11:16

Andrey
09.07.2017
17:20:59
вообще если убрать shared и immutable, адрес переменной будет одинаков.
и все теже эффекты

Denis
09.07.2017
17:27:09
Сранно

Andrey
09.07.2017
17:27:18
ну да

Denis
09.07.2017
17:28:46
вот ежели указатель на иммутабельные данные это понятно
а когда они сами каждую итерацию присываиваются это как-то странно. там const должен быть
и он должен копироваться в тред

Andrey
09.07.2017
17:29:52
дык я сам не пойму теперь.
alias call = void delegate();
call[] calls;
foreach (i; 1..3)
{
immutable int num = i;
int num2 = i;
calls ~= {
writeln("in call, num ", num, " ", &num);
writeln("in call, num2 ", num2, " ", &num2);
};
}
foreach (c; calls)
c();
даже без тредов

Google

Denis
09.07.2017
17:30:46
Какой вывод у этого кода?

Andrey
09.07.2017
17:31:04
адреса переменных одинаковые
и значения

Denis
09.07.2017
17:31:16
ну это нормально в данном случае
оптимизировалось- writeln const аргументы берёт наверно
соответственно копию num нет смысла делать реальную

Andrey
09.07.2017
17:38:21
ну вот например так
foreach (i; 1..3)
{
int num = i;
calls ~= {
writeln("in call, num ", num, " ", &num);
};
}
выводит
in call, num 2 7F32A67EE008
in call, num 2 7F32A67EE008
Я оидал, что каждый делегат будет работать со своей копией переменной.... или я туплю. а вот так все нормально:
foreach (i; 1..3)
{
() {
int num = i;
calls ~= {
//num += 1;
writeln("in call, num ", num, " ", &num);
};
}();
}

Denis
09.07.2017
17:39:36
> Я оидал, что каждый делегат будет работать со своей копией переменной
Почему?
а вот в треды я бы такое не пропускал на месте компилятора, раз может разнобой получиться
страннно это
наверно надо было бы указатели на immutabe разрешить так передавать а сами значения - нет
или он такие должен копироватьсяв тред а мы имеем баг

Dmitry
09.07.2017
18:02:00
Кажется, эмаксовый модуль падает потому, что я неправильно перевёл сишный заголовок в д. Всё, фрустрация и фтопку
эту гиблую затею. Буду говноедствовать на Си. Ненавижу эту низкоуровневую возню.

Denis
09.07.2017
18:05:36
> Кажется, эмаксовый модуль падает потому, что я неправильно перевёл сишный заголовок в д.
Люблю это делать руками. Показывай чего там
Вообще, лучше переводить только то, что ты используешь в коде
чтобы оно хоть как-то тестировалось сразу

Dmitry
09.07.2017
18:10:19
Вот как это позорище выглядит.
Вообще, лучше переводить только то, что ты используешь в коде
Да дело в том, что я настолько не в теме, что не знаю, что переводить, а что нет. Откопал туториалов, перевёл. Собралось, не упало, и показалось, что всё нормально.

Denis
09.07.2017
18:11:45
на гитхаб или в копипастилку!

Google

Dmitry
09.07.2017
18:12:02
Ок

Denis
09.07.2017
18:12:12
аргументы не такие, например

Dmitry
09.07.2017
18:14:56
Код стыдобы https://pastebin.com/LkdE0E3h
Код заголовка https://pastebin.com/xGk798LH

Denis
09.07.2017
18:18:00
alias byte int_least8_t; // это вот странно
int_least8_t это видимо тип int у коготоро только 8 бит значащие, но это не байт
первый раз такое вижу
alias c_long ptrdiff_t; // это точно неправильно, у нас есть ptrdiff_t встроенный
удали все неиспользуемые алиасы, потом используемые внимательно рассмотрим

Dmitry
09.07.2017
18:26:00
Давай забьём. Теперь мне ясно, что рано ещё в эти дебри лезть. Надо порешать задачи попроще для начала.

Denis
09.07.2017
18:26:32
Наоборот это очень просто
Никто не видел графа зависимостей пакетов с code.dlang.org ? Никто не заморачивался таким?

Dmitry
10.07.2017
07:40:27
А у других языков такое есть?

Oleg
10.07.2017
07:56:18
А причем тут другие языки?

Dmitry
10.07.2017
07:56:35
Просто посмотреть как там реализовано

Denis
10.07.2017
07:57:38
и у питона тоже вроде


Dmitry
10.07.2017
08:50:33
Магия. num из цикла вообще в тред не попадает.
Надо просто представлять, как работают замыкания в D.
При создании потока тут в примерах потокам передаются замыкания.
Замыкание = указатель на код + указатель на данные.
Какие данные - те, что упоминаются в коде.
Не все локальные переменные живут на стеке. Если какая-то локальная переменная упоминается в замыкании, то компилятор ее размещает не в стеке, а в специальном кусочке памяти в куче, который выделяется в момент входа в функцию. Т.е. например main() начинает работу, тут же отводит себе сколько-то места не стеке под локальные переменные, не участвующие в замыканиях, и одновременно выделяет на куче буфер, куда идут все локальные переменные, упоминаемые в замыканиях. Именно указатель на этот буфер будет передан, когда мы куда-то передаем замыкания. Это значит, что все такие локальные переменные живут в единственном экземпляре. Если передавать из ф-ии замыкания разным потокам, все потоки получат один и тот же укатель на замкнутые данные. Поэтому все потоки в примере выше видели одно значение локальной переменной. Они все видели физически одну и ту же переменную.
В другом примере еще была глобальная переменная. Глобальные переменные, если не __gshared, существуют в разных копиях, каждый поток ОС имеет свой собственный набор глобальных переменных. Поэтому когда один поток пишет в такую переменную, другие потоки это не видят, у них это имя означает другие переменные с другими адресами. Что мы тут и наблюдаем.


Denis
10.07.2017
08:55:17
Спасибо за разъяснения)
/me перекатывается в Prolog

Google


Andrey
10.07.2017
09:16:42
Надо просто представлять, как работают замыкания в D.
При создании потока тут в примерах потокам передаются замыкания.
Замыкание = указатель на код + указатель на данные.
Какие данные - те, что упоминаются в коде.
Не все локальные переменные живут на стеке. Если какая-то локальная переменная упоминается в замыкании, то компилятор ее размещает не в стеке, а в специальном кусочке памяти в куче, который выделяется в момент входа в функцию. Т.е. например main() начинает работу, тут же отводит себе сколько-то места не стеке под локальные переменные, не участвующие в замыканиях, и одновременно выделяет на куче буфер, куда идут все локальные переменные, упоминаемые в замыканиях. Именно указатель на этот буфер будет передан, когда мы куда-то передаем замыкания. Это значит, что все такие локальные переменные живут в единственном экземпляре. Если передавать из ф-ии замыкания разным потокам, все потоки получат один и тот же укатель на замкнутые данные. Поэтому все потоки в примере выше видели одно значение локальной переменной. Они все видели физически одну и ту же переменную.
В другом примере еще была глобальная переменная. Глобальные переменные, если не __gshared, существуют в разных копиях, каждый поток ОС имеет свой собственный набор глобальных переменных. Поэтому когда один поток пишет в такую переменную, другие потоки это не видят, у них это имя означает другие переменные с другими адресами. Что мы тут и наблюдаем.
Вопрос в том, должны ли они жить в единстенном экземпляре. В других языках, perl-е например, вот так создается каждый раз отдельный контекст для замыкания for (1..3) { my $x = $_; push @calls, sub { say $x; $x += 10 } }. Вот здесь тоже разные экземпляры будут
for (int i = 1; i < 3; i++)
{
() {
int num = i;
calls ~= {
writeln("in call, num ", num, " ", &num);
};
}();
}
Больше похоже, что в циклах как то не так работает, как интуитивно ожидается.


Dmitry
10.07.2017
09:22:18
Ну не выделять же по копии на каждой итерации любого цикла. Есть вполне четкая грань - вызов функции. Вот в последнем примере внутри цикла происходит вызов, там и выделяется память под копию нужных данных.

Andrey
10.07.2017
09:32:44
почему ж не выделять то, если выглядит так, что надо выделять? ну и с immutable вообще какая то хрень получается, иммутабле, которое меняется.

Denis
10.07.2017
09:35:29
Не, не выделять, просто тут должен быть указатель имхо а сами такие переменные запретить
потому что по сути это и получается указатель, иначе да, коннтринтуитивно
Это всё требует отдельной статья прям, имхо
immutable(int)* num нужен

Andrey
10.07.2017
10:23:23

Admin
ERROR: S client not available

Pavel
10.07.2017
10:30:15
Это похоже на нечто вроде утечки памяти. Когда из локальной области переменная уже ушла а тред с замыканием все еще на нее ссылаются.
В результате по тому адресу уже 10 раз записали другие переменные а первый тред все с этой работает.

Andrey
10.07.2017
10:39:23
скорее похоже, что все треды с одной и той же переменной работают неявно

Denis
10.07.2017
10:39:34
У нас же в tls всё
Может и immutable там лежат? Или тогда адреса бы различались?

Andrey
10.07.2017
10:41:52
дык в том и дело, что адрес одинаковый, и по факту они работают с одной и той же переменной. надо потестить еще

Pavel
10.07.2017
10:41:53

Andrey
10.07.2017
10:42:21
ну я про это и говорю)
вот кстати https://issues.dlang.org/show_bug.cgi?id=2043

Pavel
10.07.2017
11:38:51
Мда, как там только не извращаются в воркэраундах
@DmitryBubnenkov https://www.gitbook.com/ смотрел?

Google

Dmitry
10.07.2017
22:45:29
Пол года назад, надо еще раз будет глянуть. Вроде очень простую вещь хотел реализовать, но так и не осилил как вложенность обработать
Если осилю смогу очень удобную онлайн-книгу генерить
Вопрос. А как парсить данные с ресурса который требует авторизации? Curl и аналоги дишные же наверно не хранят данные о авторизации

Maxim
11.07.2017
09:04:08
авторизация какого рода?

Dmitry
11.07.2017
09:04:47
Данные через post отправляются. Дальше видимо куки ставятся

Maxim
11.07.2017
09:05:05
если http, то это передается прямо в заголовке, если нет, то id сесси почти наверняка передается как параметр куки, тогда при всех следующих запросах просто нужно передавать эти куки
куки, опять же, это просто заголовок

Denis
11.07.2017
09:06:08

Andrey
11.07.2017
09:07:27
ну куки в любом случае надо самому сохранять и передавать потом

Maxim
11.07.2017
09:08:54
ну и плюс, если это обычная форма, куда вводятся логин и пароль, она почти наверняка будет защищена csrf токеном, в этом случае алгоритм будет чуть сложнее)

Dmitry
11.07.2017
09:09:10
Получается тут кука в заголовке передается?

Maxim
11.07.2017
09:10:43
да

Andrey
11.07.2017
09:11:10
куки это и есть заголовки)

Dmitry
11.07.2017
09:11:38
т.е. чтобы спарсить данные нужно отправить пост запрос, сохранить куку и дальше просто это же куку в каждый запрос подставлять?

Maxim
11.07.2017
09:11:48
да

Andrey
11.07.2017
09:11:48
ну в простом случае да
могут быть еще тонкости, выше написали. антифроды всякие. смотришь в браузере, что там передавать надо и эмитируешь

Pavel
11.07.2017
10:25:08
Кто-нибудь умеет делать неблокирующий Socket.accept() ? В случае если на сокете ничего нету, то кидается исключение, что не очень хорошо. Выходит единственный нормальный выход это воспользоваться Socket.select() ?

Denis
11.07.2017
10:26:18
дык это, сам сокет неблокирующий?