LINUX.ORG.RU

Лисп в промышленной разработке


0

1

http://13-49-ru.blogspot.com/2010/07/blog-post_21.html

Утритесь, неосиляторы и s-exp'офобы. Лисп - не только лучший язык, но и успешно доказывает это в промышленных разработках и даже среди C++- и java-кодеров, не читавших умных книжек.

★★★★★
Ответ на: комментарий от tailgunner

>Внезапно, в отдельный процесс или нить.

пример гуя на педоне с «в отдельный процесс или нить» можно ?

sS ★★★★★
()
Ответ на: комментарий от sS

> пример гуя на педоне с «в отдельный процесс или нить» можно ?

А что вас смущает? Вы не верите, что Python есть нити? Или что там возможно асинхронное взаимодействие? Вроде базовые тривиальные вещи...

archimag ★★★
()
Ответ на: комментарий от archimag

Мне просто пример нормального гуя с возможностью асинхронной работы ...

противоположный пример я привёл.

sS ★★★★★
()
Ответ на: комментарий от sS

> Мне просто пример

«Увидеть значит поверить» (С)? Ну вы же не маленький мальчик, должны же понимать что это тривиально делается на любом языке.

archimag ★★★
()
Ответ на: комментарий от archimag

>Можно подумать, что в C++ хоть что-то threadsafe.

По крайней мере гуй вполне асинхронно работает и не блокируется рабочими воркерами.

sS ★★★★★
()
Ответ на: комментарий от antony986

>а еще там есть GIL

Есть реализации и без GIL но тут от меня «знатоки» из тщательно скрывают :))

sS ★★★★★
()
Ответ на: комментарий от sS

Короче примера я не услышал. Жаль.

Какой именно пример тебе нужен? Вот практически копия из учебника:

#!/usr/bin/env python

import gtk, gobject
import threading

gobject.threads_init()

th = None
quit = False

def endless_loop():
        global quit, l
        try:
                c = 0
                while not quit:
                        c += 1
                        gtk.gdk.threads_enter()
                        l.set_text("Counter: " + str(c))
                        gtk.gdk.threads_leave()
        finally:
                print "Thread is quitting"

def start_thread():
        global quit, th
        if th == None:
                print "Start thread"
                quit = False
                th = threading.Thread(target = endless_loop)
                th.start()

def stop_thread():
        global quit, th
        if th != None:
                print "Stop thread"
                quit = True
                th.join()
                th = None

def gtk_quit():
        stop_thread()
        gtk.main_quit()

win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.connect("destroy", lambda _: gtk_quit())
l = gtk.Label("Count:")
b1 = gtk.Button("Start")
b1.connect("clicked", lambda _: start_thread())
b2 = gtk.Button("Stop")
b2.connect("clicked", lambda _: stop_thread())
box = gtk.HBox(False)
for w in [b1, b2, l]:
        box.pack_start(w)
win.add(box)
for w in [box, b1, b2, l, win]:
        w.show()
gtk.main()

Есть реализации и без GIL

Только на VM. И, если что, приведенный выше пример не сможет задействовать несколько кор, чтобы считать счетчики.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ужос что ты накодил :)

Start thread
*** glibc detected *** python: realloc(): invalid next size: 0xb65170e8 ***
======= Backtrace: =========
/lib/libc.so.6[0xb7d47105]
/lib/libc.so.6[0xb7d4ad19]
/lib/libc.so.6(realloc+0x106)[0xb7d4ba66]
/usr/lib/libglib-2.0.so.0(g_realloc+0x3a)[0xb7b1f08a]
/usr/lib/libgdk-x11-2.0.so.0[0xb74d0d9e]
/usr/lib/libgdk-x11-2.0.so.0[0xb74d02f8]
/usr/lib/libgdk-x11-2.0.so.0(gdk_region_union+0x81)[0xb74d1811]
/usr/lib/libgdk-x11-2.0.so.0(gdk_window_invalidate_maybe_recurse+0x1ed)[0xb74d54bd]
/usr/lib/libgtk-x11-2.0.so.0[0xb778d1a0]
/usr/lib/libgtk-x11-2.0.so.0[0xb778e2c3]
/usr/lib/libgtk-x11-2.0.so.0(gtk_widget_queue_resize+0x46)[0xb7792d66]
/usr/lib/libgtk-x11-2.0.so.0[0xb765587d]
/usr/lib/libgtk-x11-2.0.so.0(gtk_label_set_text+0x7e)[0xb765645e]
/usr/lib/python2.5/site-packages/gtk-2.0/gtk/_gtk.so[0xb79f425c]
/usr/lib/libpython2.5.so.1.0(PyCFunction_Call+0x110)[0xb7ed8580]
/usr/lib/libpython2.5.so.1.0(PyEval_EvalFrameEx+0x689d)[0xb7f266cd]
/usr/lib/libpython2.5.so.1.0(PyEval_EvalCodeEx+0x73b)[0xb7f2796b]
/usr/lib/libpython2.5.so.1.0[0xb7ec4621]
/usr/lib/libpython2.5.so.1.0(PyObject_Call+0x37)[0xb7ea28f7]
/usr/lib/libpython2.5.so.1.0(PyEval_EvalFrameEx+0x40ae)[0xb7f23ede]
/usr/lib/libpython2.5.so.1.0(PyEval_EvalFrameEx+0x62c4)[0xb7f260f4]
/usr/lib/libpython2.5.so.1.0(PyEval_EvalFrameEx+0x62c4)[0xb7f260f4]
/usr/lib/libpython2.5.so.1.0(PyEval_EvalCodeEx+0x73b)[0xb7f2796b]
/usr/lib/libpython2.5.so.1.0[0xb7ec4696]
/usr/lib/libpython2.5.so.1.0(PyObject_Call+0x37)[0xb7ea28f7]
/usr/lib/libpython2.5.so.1.0[0xb7eaa0b8]
/usr/lib/libpython2.5.so.1.0(PyObject_Call+0x37)[0xb7ea28f7]
/usr/lib/libpython2.5.so.1.0(PyEval_CallObjectWithKeywords+0x7c)[0xb7f1f13c]
/usr/lib/libpython2.5.so.1.0[0xb7f56974]
/lib/libpthread.so.0[0xb7e6d310]
/lib/libc.so.6(clone+0x5e)[0xb7dbabee]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:04 51631      /usr/bin/python2.5
08049000-0804a000 rw-p 00000000 08:04 51631      /usr/bin/python2.5
0864f000-08f6f000 rw-p 00000000 00:00 0          [heap]
b6500000-b6521000 rw-p 00000000 00:00 0
b6521000-b6600000 ---p 00000000 00:00 0
b6689000-b6693000 r-xp 00000000 08:04 37254      /usr/lib/libgcc_s.so.1
b6693000-b6694000 rw-p 00009000 08:04 37254      /usr/lib/libgcc_s.so.1
b66c6000-b66c7000 ---p 00000000 00:00 0
b66c7000-b6ec6000 rw-p 00000000 00:00 0
b6ec6000-b6f5e000 r--p 00000000 08:04 1439804    /usr/share/fonts/TTF/DejaVuSans.ttf
b6f5e000-b6f6e000 r--s 00000000 08:04 291835     /var/cache/fontconfig/8d4af663993b81a124ee82e610bb31f9-x86.cache-2
b6f6e000-b6f78000 r--s 00000000 08:04 291756     /var/cache/fontconfig/d62e99ef547d1d24cdb1bd22ec1a2976-x86.cache-2
b6f78000-b6f91000 r--s 00000000 08:04 291750     /var/cache/fontconfig/f6b893a7224233d96cb72fd88691c0b4-x86.cache-2
b6f91000-b6f9b000 r-xp 00000000 08:04 604749     /lib/libnss_files-2.9.so
b6f9b000-b6f9c000 r--p 00009000 08:04 604749     /lib/libnss_files-2.9.so
b6f9c000-b6f9d000 rw-p 0000a000 08:04 604749     /lib/libnss_files-2.9.so
b6f9d000-b6fa6000 r-xp 00000000 08:04 604754     /lib/libnss_nis-2.9.so
b6fa6000-b6fa7000 r--p 00008000 08:04 604754     /lib/libnss_nis-2.9.so
b6fa7000-b6fa8000 rw-p 00009000 08:04 604754     /lib/libnss_nis-2.9.so
b6fa8000-b6fbd000 r-xp 00000000 08:04 604745     /lib/libnsl-2.9.so
b6fbd000-b6fbe000 r--p 00014000 08:04 604745     /lib/libnsl-2.9.so
b6fbe000-b6fbf000 rw-p 00015000 08:04 604745     /lib/libnsl-2.9.so
b6fbf000-b6fc1000 rw-p 00000000 00:00 0
b6fc1000-b6fc8000 r-xp 00000000 08:04 604746     /lib/libnss_compat-2.9.so
b6fc8000-b6fc9000 r--p 00006000 08:04 604746     /lib/libnss_compat-2.9.so
b6fc9000-b6fca000 rw-p 00007000 08:04 604746     /lib/libnss_compat-2.9.so
b6fcc000-b6fcd000 rw-p 00000000 00:00 0
b6fcd000-b6fcf000 r-xp 00000000 08:04 547559     /usr/lib/pango/1.6.0/modules/pango-basic-fc.so
b6fcf000-b6fd0000 rw-p 00001000 08:04 547559     /usr/lib/pango/1.6.0/modules/pango-basic-fc.so
b6fd0000-b6fd1000 r--s 00000000 08:04 344577     /var/cache/fontconfig/4c599c202bc5c08e2d34565a40eac3b2-x86.cache-2
b6fd1000-b6fd3000 r--s 00000000 08:04 353328     /home/ss/.fontconfig/8bb5544b4a907d5ca58f819f8409112e-x86.cache-2
b6fd3000-b6fd8000 r--s 00000000 08:04 346259     /var/cache/fontconfig/f349e9996a5320f6dd491cedd2b1f964-x86.cache-2
b6fd8000-b6fda000 r-xp 00000000 08:04 604467     /usr/lib/gconv/KOI8-R.so
b6fda000-b6fdb000 r--p 00001000 08:04 604467     /usr/lib/gconv/KOI8-R.so
b6fdb000-b6fdc000 rw-p 00002000 08:04 604467     /usr/lib/gconv/KOI8-R.so
b6fdc000-b6ffc000 r--p 00000000 08:04 604067     /usr/share/locale/ru/LC_MESSAGES/libc.mo
b6ffc000-b7000000 r-xp 00000000 08:04 48584      /usr/lib/python2.5/lib-dynload/collections.so
b7000000-b7001000 rw-p 00004000 08:04 48584      /usr/lib/python2.5/lib-dynload/collections.so
b7001000-b7004000 r-xp 00000000 08:04 48591      /usr/lib/python2.5/lib-dynload/time.so
b7004000-b7006000 rw-p 00002000 08:04 

... снип - иначе ЛОР не пропускает по размеру ....

1278545    /usr/lib/libcairo.so.2.17.5
b743a000-b743c000 rw-p 0005e000 08:04 1278545    /usr/lib/libcairo.so.2.17.5
b743c000-b7476000 r-xp 00000000 08:04 128679     /usr/lib/libpango-1.0.so.0.2002.3
b7476000-b7478000 rw-p 00039000 08:04 128679     /usr/lib/libpango-1.0.so.0.2002.3
b7478000-b748e000 r-xp 00000000 08:04 1289313    /usr/lib/libgdk_pixbuf-2.0.so.0.1200.12
b748e000-b748f000 rw-p 00016000 08:Аварийный останов

sS ★★★★★
()
Ответ на: комментарий от sS

> Ужос что ты накодил :)

УМВР %)

Понятно, что я мог пропустить где-то магический вызов (давно гуев не делал), но асинхронный гуй делается именно так.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>но асинхронный гуй делается именно так.

Оно как раз падает при попытке писать в гуй из твоего потока

sS ★★★★★
()
Ответ на: комментарий от sS

Оно как раз падает при попытке писать в гуй из твоего потока

Походу, я смешал два способа синхронизации. Попробуй этот вариант.

#!/usr/bin/env python

import gtk, gobject
import threading

gtk.gdk.threads_init()

th = None
quit = False

def endless_loop():
        global quit, l
        try:
                c = 0
                while not quit:
                        c += 1
                        l.set_text("Counter: " + str(c))
        finally:
                print "Thread is quitting"

def start_thread():
        global quit, th
        if th == None:
                print "Start thread"
                quit = False
                th = threading.Thread(target = endless_loop)
                th.start()

def stop_thread():
        global quit, th
        if th != None:
                print "Stop thread"
                quit = True
                th.join()
                th = None

def gtk_quit():
        stop_thread()
        gtk.main_quit()

win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.connect("destroy", lambda _: gtk_quit())
l = gtk.Label("Count:")
b1 = gtk.Button("Start")
b1.connect("clicked", lambda _: start_thread())
b2 = gtk.Button("Stop")
b2.connect("clicked", lambda _: stop_thread())
box = gtk.HBox(False)
for w in [b1, b2, l]:
        box.pack_start(w)
win.add(box)
for w in [box, b1, b2, l, win]:
        w.show()
gtk.gdk.threads_enter()
gtk.main()
gtk.gdk.threads_leave()
tailgunner ★★★★★
()
Ответ на: комментарий от rg-400

>у меня работает :)

Мы до самого интересного так и не дошли :)

sS ★★★★★
()
Ответ на: комментарий от antony986

1. программистов на лиспе реалнь нет

Есть. Частенько вижу, что кто-то крутящийся в лисповой сфере вдруг оказывается в лисповой конторе.

2. а те что есть захотят много денег

Скажем так, средне по отрасли ;)

3. как по поводу быстрой разработки гуя?

В LispWorks на CAPI это делается быстрее, чем на Qt.

4. как там SBCL поживает под вендой?

Нормально. Через пару месяцев мультитрединг в апстрим будет смержен.

mv ★★★★★
()
Ответ на: комментарий от tailgunner

Выдает рандомные значения в Count и валится:

$./sync.py
** Message: pygobject_register_sinkfunc is deprecated (GtkWindow)
** Message: pygobject_register_sinkfunc is deprecated (GtkInvisible)
** Message: pygobject_register_sinkfunc is deprecated (GtkObject)
Start thread
Segmentation fault (core dumped)
$./sync.py
** Message: pygobject_register_sinkfunc is deprecated (GtkWindow)
** Message: pygobject_register_sinkfunc is deprecated (GtkInvisible)
** Message: pygobject_register_sinkfunc is deprecated (GtkObject)
Start thread
sync.py:55: PangoWarning: shaping failure, expect ugly output. shape-engine='BasicEngineFc', font='DejaVu Sans 9.9990234375', text=''
  gtk.main()
sync.py:55: PangoWarning: pango_layout_get_line_count: assertion `layout != NULL' failed
  gtk.main()
sync.py:55: GtkWarning: gdk_draw_layout: assertion `PANGO_IS_LAYOUT (layout)' failed
  gtk.main()
**
Gdk:ERROR:gdkregion-generic.c:1108:miUnionNonO: assertion failed: (y1 < y2)
Aborted (core dumped)
$./sync.py
** Message: pygobject_register_sinkfunc is deprecated (GtkWindow)
** Message: pygobject_register_sinkfunc is deprecated (GtkInvisible)
** Message: pygobject_register_sinkfunc is deprecated (GtkObject)
Start thread
sync.py:55: PangoWarning: shaping failure, expect ugly output. shape-engine='BasicEngineFc', font='DejaVu Sans 9.9990234375', text=''
  gtk.main()
sync.py:55: PangoWarning: pango_layout_get_line_count: assertion `layout != NULL' failed
  gtk.main()
sync.py:55: GtkWarning: gdk_draw_layout: assertion `PANGO_IS_LAYOUT (layout)' failed
  gtk.main()
**
Gdk:ERROR:gdkregion-generic.c:1191:miUnionO: assertion failed: (pNextRect[-1].x1<pNextRect[-1].x2)
Aborted (core dumped)
$./sync.py
** Message: pygobject_register_sinkfunc is deprecated (GtkWindow)
** Message: pygobject_register_sinkfunc is deprecated (GtkInvisible)
** Message: pygobject_register_sinkfunc is deprecated (GtkObject)
Start thread
sync.py:55: PangoWarning: shaping failure, expect ugly output. shape-engine='BasicEngineFc', font='DejaVu Sans 9.9990234375', text=''
  gtk.main()
sync.py:55: GtkWarning: gdk_draw_layout: assertion `PANGO_IS_LAYOUT (layout)' failed
  gtk.main()
sync.py:55: PangoWarning: pango_layout_get_line_count: assertion `layout != NULL' failed
  gtk.main()
Stop thread
Thread is quitting
Start thread
sync.py:55: PangoWarning: Invalid UTF-8 string passed to pango_layout_set_text()
  gtk.main()
sync.py:55: PangoWarning: pango_layout_get_pixel_extents: assertion `PANGO_IS_LAYOUT (layout)' failed
  gtk.main()
Segmentation fault (core dumped)

ipc
()
Ответ на: комментарий от cathode

" ... Есть у нас большой человек с огромным опытом, и он, в числе прочего, причёсывает дизайн системы. ... " - там сидит один человек, который что-то понимает в лиспе и вычищает за всеми говно из кода. Вот и весь секрет.

Человек, писавший Аду, первый Апаш и сидевший в боардс Апаш Фаундейшн чужое говно не чистит. Говно сами говновоятели уже вычистили, кстати, всё чистенько.

Основатель фирмы на лиспе пишет на два годе больше, чем мне лет ;)

mv ★★★★★
()
Ответ на: комментарий от mv

>> 1. программистов на лиспе реалнь нет

Есть. Частенько вижу, что кто-то крутящийся в лисповой сфере вдруг оказывается в лисповой конторе.


Но согласись что это штучный товар.

sS ★★★★★
()
Ответ на: комментарий от rg-400

> у меня работает :)

У меня тоже, но «тестирование не доказывает отсуствие ошибок» (с)

tailgunner ★★★★★
()
Ответ на: комментарий от mv

>Есть. Частенько вижу, что кто-то крутящийся в лисповой сфере вдруг оказывается в лисповой конторе.

последние 23 года меня не покидает ощущение, что я живу в какой-то заднице

В LispWorks на CAPI это делается быстрее, чем на Qt.

если честно слабо верится, но вам как спецу виднее, не буду спорить

Нормально. Через пару месяцев мультитрединг в апстрим будет смержен.

хм, прогресс налицо

antony986
()
Ответ на: комментарий от antony986

последние 23 года меня не покидает ощущение, что я живу в какой-то заднице

Меня тоже, поэтому в 26 лет я из задницы уехал ;)

если честно слабо верится, но вам как спецу виднее, не буду спорить

У нас GUI (морды для софтовых валидаторов) именно на CAPI пишутся, там кода, собственно, всего ничего.

mv ★★★★★
()
Ответ на: комментарий от sS
$ taskset 0x00000001 ./sync.py
** Message: pygobject_register_sinkfunc is deprecated (GtkWindow)
** Message: pygobject_register_sinkfunc is deprecated (GtkInvisible)
** Message: pygobject_register_sinkfunc is deprecated (GtkObject)
Start thread
Stop thread
Thread is quitting
Start thread
Stop thread
Thread is quitting
Start thread
Stop thread
Thread is quitting

Если привязать к одному процессору (ядру), работает корректно.

ipc
()
Ответ на: комментарий от ipc

Если привязать к одному процессору (ядру), работает корректно.

Прикольно. Какая система и работает ли это вариант на двух корах?

#!/usr/bin/env python

import gtk, gobject
import threading

gtk.gdk.threads_init()

th = None
quit = False

def endless_loop():
        global quit, l
        try:
                c = 0
                while not quit:
                        c += 1
                        gtk.gdk.threads_enter()
                        l.set_text("Counter: " + str(c))
                        gtk.gdk.threads_leave()
        finally:
                print "Thread is quitting"

def start_thread():
        global quit, th
        if th == None:
                print "Start thread"
                quit = False
                th = threading.Thread(target = endless_loop)
                th.start()

def stop_thread():
        global quit, th
        if th != None:
                print "Stop thread"
                gtk.gdk.threads_leave()
                quit = True
                th.join()
                gtk.gdk.threads_enter()
                th = None

def gtk_quit():
        stop_thread()
        gtk.main_quit()

win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.connect("destroy", lambda _: gtk_quit())
l = gtk.Label("Count:")
b1 = gtk.Button("Start")
b1.connect("clicked", lambda _: start_thread())
b2 = gtk.Button("Stop")
b2.connect("clicked", lambda _: stop_thread())
box = gtk.HBox(False)
for w in [b1, b2, l]:
        box.pack_start(w)
win.add(box)
for w in [box, b1, b2, l, win]:
        w.show()
gtk.gdk.threads_enter()
gtk.main()
gtk.gdk.threads_leave()

tailgunner ★★★★★
()
Ответ на: комментарий от mv

> Нет, просто это неправда :) Офисы в Париже и Бостоне.

Хм, где-то на сайте я видел что-то про Индию. Может не так понял.

archimag ★★★
()
Ответ на: комментарий от tailgunner

работает ли это вариант на двух корах?

Yup.

$ taskset 0x00000003 ./sync2.py
** Message: pygobject_register_sinkfunc is deprecated (GtkWindow)
** Message: pygobject_register_sinkfunc is deprecated (GtkInvisible)
** Message: pygobject_register_sinkfunc is deprecated (GtkObject)
Start thread
Stop thread
Thread is quitting
Start thread
Stop thread
Thread is quitting
Start thread
Stop thread
Thread is quitting

ipc
()
Ответ на: комментарий от tailgunner

Ключевое слово global прикалывает. Хотя в этом что-то есть. Меньше глобальных переменных - лучше программер :)

dave ★★★★★
()
Ответ на: комментарий от antony986

любой хороший специалист - это штучный товар, это относится ко всем областям, а не только к языкам

ott ★★★★★
()
Ответ на: комментарий от tailgunner

в python нити native из ОС и упираются в GIL
причем так бодро упираются, что программа может с ними работать в два раза дольше на одной задаче
нормальную многонитевость с некоторыми ограничениями можно реализовать с Си\Си++ расширении

hizel ★★★★★
()
Ответ на: комментарий от hizel

> в python нити native из ОС и упираются в GIL

Не понял этой фразы. Нативные нити в GIL не упираются, а те, которые упираются - не нативные, а green.

программа может с ними работать в два раза дольше на одной задаче

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

нормальную многонитевость с некоторыми ограничениями можно реализовать с Си\Си++ расширении

конечно, но стоит ли оно того? Если бы мне сейчас пришлось писать для многоядерника на Питоне, я бы сначала попробовал multipfrocessing.

tailgunner ★★★★★
()
Ответ на: комментарий от dave

> Меньше глобальных переменных - лучше программер :)

Я тоже люблю простые и понятные критерии. С ними так... уютно.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

хотя, справедливости ради, у меня _с третьего раза_ взлетело.

дебиан, питон 2.5.5, 4 ведра.

Rastafarra ★★★★
()
Ответ на: комментарий от tailgunner

>> в python нити native из ОС и упираются в GIL

Не понял этой фразы. Нативные нити в GIL не упираются, а те, которые упираются - не нативные, а green.


http://docs.python.org/library/thread.html#module-thread
The module is optional. It is supported on Windows, Linux, SGI IRIX, Solaris 2.x, as well as on systems that have a POSIX thread (a.k.a. “pthread”) implementation.

http://docs.python.org/c-api/init.html#thread-state-and-the-global-interprete...
Therefore, the rule exists that only the thread that has acquired the global interpreter lock may operate on Python objects or call Python/C API functions.

какой green? где в пистоне green?

hizel ★★★★★
()
Ответ на: комментарий от hizel

> какой green? где в пистоне green?

Стандартные CPython-нити не green, здесь я ошибся.

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.