- 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
include std/socket.e as s
include std/error.e as err
constant PORT = 5050
constant BACKLOG = 5
procedure die(object result, sequence action)
printf(2, "Error %d in %s", {result, action})
err:crash(action)
end procedure
procedure ensure_zero(integer result, sequence action)
if result != 0 then
die(result, action)
end if
end procedure
function ensure_seq(object result, sequence action)
if atom(result) then
die(result, action)
end if
return result
end function
enum SOCKET, READ, WRITE, ERROR
constant PHRASE = "Hello from Euphoria\n"
procedure client_proc(sequence socket)
while 1 do
for i = 1 to length(PHRASE) do
sequence result = s:select({}, socket, {}, 0, 100)
sequence result_s = result[1]
if result_s[WRITE] = 1 then
s:send(socket, {PHRASE[i]}, 0)
end if
task_yield()
end for
end while
end procedure
constant client_proc_id = routine_id("client_proc")
sequence server = ensure_seq(s:create(s:AF_INET, s:SOCK_STREAM, 0), "create")
ensure_zero(s:bind(server, "127.0.0.1", PORT), "bind")
ensure_zero(s:listen(server, BACKLOG), "listen")
while 1 do
sequence listen_result = s:select(server, {}, {}, 0, 100)
if listen_result[1][READ] = 1 then
sequence client = ensure_seq(s:accept(server), "accept")
printf(1, "Here comes %s\n", {client[2]})
atom task = task_create(client_proc_id, {client[1]})
task_schedule(task, {0.5, 0.5})
end if
task_yield()
end while
MAKAKA # 0
К сожалению, неблокирующие сокеты не работают кросс-платформенно, но работает select.
Осталось добавить кольцевой буфер, и можно сделать чат.
С помощью утилиты euc можно получить статически слинкованный бинарник
guest # 0
Меня теперь еще три дня не отпустит
пиздец конечно тормозит оно, лол
bormand # 0 ⇈
Ну правильно, если по 100 попугаев в каждом селекте спать... Больше тасок - больше лагов.
Какое масштабирование )))
guest # 0 ⇈
на самом деле он спит в тасках только если некуда писать, но клиентов он ждет по 1/10 секунды, да
guest # 0 ⇈
bormand # 0 ⇈
Эм, а там никаких ивентов нету что ли?
guest # 0 ⇈
узнать о наличии данных можно только селектом.
bormand # 0 ⇈
guest # 0 ⇈
Будет не оч красивый код кмк
сам селект ничего не будит: он блокируюется на 100 попугаев (или сколько напишешь) и возврашает сокеты, ну как селект и делает
а будить нужно самому
>нет такого
кажется, что нет
https://openeuphoria.org/docs/std_socket.html
сокет про таски нич не знает, а таски не знают про сокет
bormand # 0 ⇈
З.Ы. Ещё task_suspend какой-то есть.
guest # 0 ⇈
>task_suspend
он стопает таску до момента, когда ты явно снова ее запустить черещ schedule
шедудер выбирает все незасуспенженные таски, и в соответствии с их приоритетом их дергает, если пришло время
можно задать или приоритет или время
bormand # 0 ⇈
А должен select/poll, как все нормальные юзермодные шедулеры. И резюмить таски, которые "заблокировались" на чтении или записи. Но, видимо, автор не осилил это в своём курсаче.
guest # 0 ⇈
но помни: это писалось под атари ст и портировалось под дос потом
When the scheduler must delay, it calls sleep(), unless the required delay is very short. sleep() lets the operating system run other programs.
bormand # 0 ⇈
Такова жизнь... Виндовые шедулеры ещё и про оконные сообщения знают. Как иначе на одном треде сделать быструю реакцию без 100% загрузки проца?
guest # 0 ⇈
А окна мы как-то обсуждали: они знают, какое окно сейчас активно. А прыщешедулер не знает. Потому винда более отзывчива
bormand # 0 ⇈
guest # 0 ⇈
ConnectAsync
https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.connectasync?view=netcore-3.1
bormand # 0 ⇈
Можешь тогда себе сам слепить кошерный шедулер.
Сделай лоу-приорити таску которая тупо спит в select'е и пробуждает таски для которых есть готовые сокеты. И обёртки для read, write и accept которые добавляют пару (сокет, self) в массив для селекта и суспендятся.
Поскольку таска лоу приорити, она будет вызываться только когда все "события" обработаны. Ну если я правильно понимаю что такое приоритет.
guest # 0 ⇈
Написать свой шедулер, который знает про сокеты )
Приоритет влияет на то, какую следующую таску запустит эйфориный шедулер.
Когда ты говоришь task_yield() ты передаешь управление шедулеру.
У него есть список тасок. Он выбирает нужную, и запускает ее.
Кстати, воткнуться можно и на чтении из сокета и на письме в него: Они всё таки блокирующие. Сделать неблокирующим можно только на линукс (под винду API в эфцории нет).
Так что нужно или дергать нативные API винды напрямую (там довольно неплохо сделан интероп) или смириться с тем, что пока ты пишешь гигабайт в сокет клиенту -- остальные таски сосут лапу.
Fike # 0 ⇈
там кстати говорили что есть такая хуйня, что на самом деле даже неблокирующие сокеты блокирующие, если буфер заполнен - в этом случае сисколл просто стоит и ждет, пока сможет запихнуть данные
какая производительность )))
guest # 0 ⇈
Классический юникс вей это нафоркать детишек по одному на десяток клиентов, и селектом/полом их обслуживать.
Если воткнет, так пострадает группа товарищей, но не все кмк
bormand # 0 ⇈
Есть пруфы?
MAPTbIwKA # 0 ⇈
Обе хуйни вроде одно и тоже, но одна пришла из бзды, а вторая из SysV
Fike # 0 ⇈
MAKAKA # 0 ⇈
Fike # 0 ⇈
MAKAKA # 0 ⇈
guest # 0 ⇈
MAKAKA # 0 ⇈
Люди не решают сами когда им рождаться
guest # 0 ⇈
MAKAKA # 0 ⇈
guest # 0 ⇈
MAKAKA # 0 ⇈
кто же это?|
guest # 0 ⇈
Desktop # 0 ⇈
MAKAKA # 0 ⇈
guest # 0 ⇈
Desktop # 0 ⇈
defecate-plusplus # 0 ⇈
Desktop # 0 ⇈
guest # 0 ⇈
Desktop # 0 ⇈
defecate-plusplus # 0 ⇈
В воцапе дико бесит недоразвитость. Особенно на десктопе. Терплю это недоразумение ради < 5 контактов
rotoeb # 0 ⇈
guest # 0 ⇈
Fike # 0 ⇈
MAKAKA # 0 ⇈
Fike # 0 ⇈
guest # 0 ⇈
Fike # 0 ⇈
неравноценная какая-то сделка короч
guest # 0 ⇈
Fike # 0 ⇈
да, я из спб
guest # 0 ⇈
Fike # 0 ⇈
MAKAKA # 0 ⇈
guest # 0 ⇈
MAKAKA # 0 ⇈
Fike # 0 ⇈
MAKAKA # 0 ⇈
Desktop # 0 ⇈
Fike # 0 ⇈
guest # 0
какой эксперт ))
https://it.wikireading.ru/13685
bormand # 0 ⇈
guest # 0 ⇈
Кстати, XENIX завозили и на 286 вроде: там уже был защищенный режим (хотя и без страничек).
Как жаль, что MS запилили свой NT на основе VMS, а не Unix. Насколько мир был бы лучше, ах
Saehrimnir # 0 ⇈
MAPTbIwKA # 0 ⇈
tl;tr
In fact, you can read sections of VAX/VMS Internals and Data Structures (Digital Press) as an accurate description of NT internals simply by translating VMS terms to NT terms.
Saehrimnir # 0 ⇈
MAPTbIwKA # 0 ⇈
Ты просто откртываешь какой-то объект: \Foo\Bar\Bus, и шлешь ему ioctl. А ядро перенаправляет их драйверу, создавшему этот объект (на самом деле там фильтры есть, еще хуйня какая-то, Борманд знает вроде), но в целом именно так.
Все эти ваши C:\ это вообще симлинки
bormand # 0 ⇈
Юзермод: C:\foo\bar
Ядро: \\.\Volume5\foo\bar
Драйвер файлухи для \\.\Volume5: \foo\bar
MAPTbIwKA # 0 ⇈
MAPTbIwKA # 0 ⇈
MAKAKA # 0 ⇈
Но на x86 не встанет