Куча говна / Говнокод #27062 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 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 MAKAKA, (Updated )

Комментарии (72) RSS

  • Дамы и господа, представляю вам демонстрацию кооперативной многозадачности и сетевого программирования на эйфории.

    К сожалению, неблокирующие сокеты не работают кросс-платформенно, но работает select.

    Осталось добавить кольцевой буфер, и можно сделать чат.

    С помощью утилиты euc можно получить статически слинкованный бинарник
    Ответить
  • Десктоп, зачем ты мне это показал?
    Меня теперь еще три дня не отпустит

    пиздец конечно тормозит оно, лол
    Ответить
    • > пиздец конечно тормозит

      Ну правильно, если по 100 попугаев в каждом селекте спать... Больше тасок - больше лагов.

      Какое масштабирование )))
      Ответить
      • правильно. А если спать один попугай, то я буду бизивейтом

        на самом деле он спит в тасках только если некуда писать, но клиентов он ждет по 1/10 секунды, да
        Ответить
      • ps: по уму конечно нужно иметь один селект на все говно, и просто улеличивать кол-во сокетов, но тогда не получится иметь по таске на клиента
        Ответить
        • > не получится иметь по таске на клиента

          Эм, а там никаких ивентов нету что ли?
          Ответить
          • судя по доке нет, ну или я криво искал

            узнать о наличии данных можно только селектом.
            Ответить
            • Ну суть не в том, чтобы узнать. Суть в том, чтобы засуспендить таску до тех пор, пока ты сам не захочешь её пробудить, получив что-то в селекте. Неужели там нет такого примитива?
              Ответить
              • ну все равно у меня будет одна таска, которая селектит все сокеты, а получив сокет с данными -- пробудит соответствующую таску

                Будет не оч красивый код кмк

                сам селект ничего не будит: он блокируюется на 100 попугаев (или сколько напишешь) и возврашает сокеты, ну как селект и делает

                а будить нужно самому

                >нет такого
                кажется, что нет
                https://openeuphoria.org/docs/std_socket.html


                сокет про таски нич не знает, а таски не знают про сокет
                Ответить
                • Вроде можно через task_schedule задать себе интервал побольше. И тогда task_yield не сразу вернётся и ты не будешь грузить проц на 100% даже с нулевой задержкой в селекте. Проверь.

                  З.Ы. Ещё task_suspend какой-то есть.
                  Ответить
                  • это верно: когда эфйорийному шедулеру нече делать, он спит (всмысле реально sleep() делает), но ведь тогда я не смогу печатать с желаемой скоростью!

                    >task_suspend
                    он стопает таску до момента, когда ты явно снова ее запустить черещ schedule

                    шедудер выбирает все незасуспенженные таски, и в соответствии с их приоритетом их дергает, если пришло время

                    можно задать или приоритет или время
                    Ответить
                    • > всмысле реально sleep() делает

                      А должен select/poll, как все нормальные юзермодные шедулеры. И резюмить таски, которые "заблокировались" на чтении или записи. Но, видимо, автор не осилил это в своём курсаче.
                      Ответить
                      • тогда шедулеру пришлось бы знать про таски)

                        но помни: это писалось под атари ст и портировалось под дос потом

                        When the scheduler must delay, it calls sleep(), unless the required delay is very short. sleep() lets the operating system run other programs.
                        Ответить
                        • > шедулеру пришлось бы знать про сокеты

                          Такова жизнь... Виндовые шедулеры ещё и про оконные сообщения знают. Как иначе на одном треде сделать быструю реакцию без 100% загрузки проца?
                          Ответить
                    • > приоритет

                      Можешь тогда себе сам слепить кошерный шедулер.

                      Сделай лоу-приорити таску которая тупо спит в select'е и пробуждает таски для которых есть готовые сокеты. И обёртки для read, write и accept которые добавляют пару (сокет, self) в массив для селекта и суспендятся.

                      Поскольку таска лоу приорити, она будет вызываться только когда все "события" обработаны. Ну если я правильно понимаю что такое приоритет.
                      Ответить
                      • какой пирдолинг ))
                        Написать свой шедулер, который знает про сокеты )

                        Приоритет влияет на то, какую следующую таску запустит эйфориный шедулер.

                        Когда ты говоришь task_yield() ты передаешь управление шедулеру.
                        У него есть список тасок. Он выбирает нужную, и запускает ее.

                        Кстати, воткнуться можно и на чтении из сокета и на письме в него: Они всё таки блокирующие. Сделать неблокирующим можно только на линукс (под винду API в эфцории нет).
                        Так что нужно или дергать нативные API винды напрямую (там довольно неплохо сделан интероп) или смириться с тем, что пока ты пишешь гигабайт в сокет клиенту -- остальные таски сосут лапу.
                        Ответить
                        • > Сделать неблокирующим можно только на линукс

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

                          какая производительность )))
                          Ответить
                          • Вообще это всё новомодная хуйня, конечно.
                            Классический юникс вей это нафоркать детишек по одному на десяток клиентов, и селектом/полом их обслуживать.

                            Если воткнет, так пострадает группа товарищей, но не все кмк
                            Ответить
                          • Выглядит как бага. Должны прочитать или отправить сколько получится и вернуть управление.

                            Есть пруфы?
                            Ответить
  • >про DOS я вообще молчу — урезанная версия XENIX, которая, в свою очередь является урезанной версией UNIX)

    какой эксперт ))
    https://it.wikireading.ru/13685
    Ответить
    • Вообще пишут, что майкрософт вдохновлялся "XENIX" когда прикручивал в "DOS" каталоги и хендлы файлов.
      Ответить
      • Вполне может быть, но классический DOS к Xenix отношения не имел, и если кого и косплеил, так это CP/M.

        Кстати, XENIX завозили и на 286 вроде: там уже был защищенный режим (хотя и без страничек).

        Как жаль, что MS запилили свой NT на основе VMS, а не Unix. Насколько мир был бы лучше, ах
        Ответить
        • «NT» больше похожа на «OS/2», чем на «VMS». Хотя да, вся эта питушня на «Unix» не похожа.
          Ответить
            • Интересно. Но в любом случае там много всего перепитушили. В «VMS» пути к файлам пишутся примерно в таком стиле:
              SYSTEM$DISC$:[DIR.SUBDIR.SUBSUBDIR]readme.txt;1
              А в «NT» — в досовском.
              Ответить
              • Ядру NT (мы же про ядро?) и Executive всё равно на пути к файлу.

                Ты просто откртываешь какой-то объект: \Foo\Bar\Bus, и шлешь ему ioctl. А ядро перенаправляет их драйверу, создавшему этот объект (на самом деле там фильтры есть, еще хуйня какая-то, Борманд знает вроде), но в целом именно так.

                Все эти ваши C:\ это вообще симлинки
                Ответить
                • Драйвер файлухи получает весь хвост после имени тома, емнип. Т.е. у файлов реальных объектов как таковых нет, только у томов.

                  Юзермод: C:\foo\bar
                  Ядро: \\.\Volume5\foo\bar
                  Драйвер файлухи для \\.\Volume5: \foo\bar
                  Ответить
                  • На самом деле там еще ObjectManager который ссылку резолвит, и фильтры файловой систсемы (аппер, ловер) а после драйвера файлухи еще вроде слой кеширования блочных устройств, и посылка IPR в Harddrive, и там PnPManager и еще фильтры, но я не Maxim S. Shatskih, и без книжки Руссиновича конечно всю цепочку не восстанлвлю по памяти
                    Ответить

Добавить комментарий

Из-за тебя ушел bormand, guest!

    А не использовать ли нам bbcode?


    8