Модераторы: ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Tkx и долговыполняющиеся функции 
:(
    Опции темы
alezzz
Дата 19.5.2011, 21:21 (ссылка)  | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: нет
Всего: 14



Нужно сделать GUI для одной программы, выбрал Tkx. Вобщем примерно такой код:
Код

use Tkx;


$run = 0;

#
# кнопки, текстовые поля и т.д.
# функции обработки нажатия клавиш 
#

loop();

Tkx::MainLoop();

sub loop{
    if ($run){
    #  тут что-то делаю
    }
    Tkx::after(100, \&loop);
}


Есть кнопка "Старт", которая делает $run=1 и кнопка "Стоп", которая делает $run=0. Функция loop периодичекси смотрит $run == 1, и если true  то начинает что-то делать, и вот это что-то может затянуться на минуты (а может и часы) и все это время функция забирает весь процесс на себя, никакую кнопку не нажать, все выводы внутри функции в текстовые поля не отображаются пока не отработает функция. 

Как сделать правильно? И желательно без fork. Нет ли какой функции чтоб на время отдать управление MainLoop и потом продолжить дальше?

И может кто знает ссылку на хорошую документацию по Tkx.

Это сообщение отредактировал(а) alezzz - 19.5.2011, 21:23
PM MAIL   Вверх
Pfailed
Дата 19.5.2011, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 1
Всего: 39



А что делает эта функция? Какие-то вычисления или операции ввода-вывода? Если первое, то по хорошему нужен отдельный поток/процесс для неё. Со вторым Tk должен справиться без ветвлений.


--------------------
PM MAIL   Вверх
alezzz
Дата 19.5.2011, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: нет
Всего: 14



Все начальные данные поступают из entry и text. Сама функция занимается скорее вычислениями, а если точнее через LWP::UserAgent отправляет запросы, много. Скорость работы функции также зависит от скорости интернет. Есть несколько вложеных циклов (for, while), вызовы других функций. Попробовал заменить циклы условиями, которые срабатывают  по определеннолму значению переменной, но все настолько запутано получается, к тому-же приходится подгонять имеющийся код вместо написания нового... вобщем жуть. 
А вот с процессами проблема, делается под Windows, пробовал я раньше сделать fork под windows, чот-то не получилось.
PM MAIL   Вверх
Pfailed
Дата 19.5.2011, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 1
Всего: 39



LWP::UserAgent это ни что инное, как операции ввода-вывода по сети. Соответственно потоки и процессы тут не нужны.
Все задержки сводятся  к ожиданию прихода данных от удаленной стороны. Если чуть углубиться, то происходят блокировки при чтении из сокетов, когда данных в сокете еще нет. В Tk есть средства позволяющие осуществлять неблокирующий ввод-вывод. Просто просим Tk чтобы он уведомил нас когда данные станут доступны для чтения. Таким образом программа наша больше не блокируется. В этом и есть суть событийно ориентированного подхода. Получили событие - отреагировали.  Будь то нажатие кнопки или приход данных по сети.
Все это хорошо, но есть и минусы. Логика программы сильно усложняется: нужно писать кучу коллбэков и передавать между ними данные.
Как я вижу у вас тут есть несколько путей:
1. Обойтись Net::HTTP::NB и возможностями Tk.
2. Посмотреть на событийные машины которые дружат с Tk и имеют уже готовый http клиент. Насколько знаю AnyEvent и POE могут подойти
3. Ознакомиться с модулем Coro и Coro::LWP

Первый вариант самый аскетичный, большинство работы нужно проделать вручную.
Второй вариант более прост в реализации, но придётся сперва разобраться в этих самых событийных машинах (AnyEvent мне показался проще).
Третий вариант на мой взгляд самый простой. Интерфейс Coro во многом похож на интерфейс модуля threads. И стиль написания кода здесь уже привычный, а не событийно ориентированный. Получится даже воспользоваться LWP::UserAgent. Мой восторг по поводу Coro можно прочитать в одной из тем

Плохо то, что вы работает в  windows. Кто знает на какие грабли придётся наступить, ведь сокеты в windows весьма спецефичны.


--------------------
PM MAIL   Вверх
alezzz
Дата 20.5.2011, 07:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: нет
Всего: 14



Pfailed, спасибо, попробую сначала Coro, посмотрю что получится.
PM MAIL   Вверх
Pfailed
Дата 20.5.2011, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 1
Всего: 39



С Coro это действительно очень просто. Ниже пример: кнопка по прежнему реагирует на нажатие в то время как LWP качает большой файл. Работает ли на Windows?

Код

use Tk;
use Coro::LWP;
use AnyEvent;
use Coro;
use Coro::AnyEvent;
use LWP::Simple;

my $mw = MainWindow->new();
$mw->Button(-text => 'Push me', -command => sub { $mw->Dialog(-text => 'Just works')->Show })->pack();
$mw->geometry('200x100');

async {
    getstore('ftp://ftp.microsoft.com/developr/Interix/interix22/gcc.source.shlib.0.2.tar',  'gcc.source.shlib.0.2.tar');
};

MainLoop;




--------------------
PM MAIL   Вверх
alezzz
Дата 20.5.2011, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: нет
Всего: 14



Цитата(Pfailed @  20.5.2011,  11:48 Найти цитируемый пост)
Работает ли на Windows?


smile вот с этим проблема, стоит ActiveState, через ppm модуль не установился... пока отложил Coro, решил покрутить POE
PM MAIL   Вверх
Pfailed
Дата 20.5.2011, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 1
Всего: 39



Когда отказывает ppm может помочь cpan: http://forum.vingrad.ru/index.php?showtopi...t&p=2334231


--------------------
PM MAIL   Вверх
alezzz
Дата 20.5.2011, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: нет
Всего: 14



на *nix да, на windows не все так просто:
Код

       cl -c    -nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_ST
RICT -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT
_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX -MD -Zi -DNDEBUG
 -O1    -DVERSION=\"5.372\"  -DXS_VERSION=\"5.372\"  "-IC:\Perl\lib\CORE"  -DCOR
O_LOSER -DCORO_STACKSIZE=16384 -DCORO_STACKGUARD=4 State.c
"cl" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
NMAKE : fatal error U1077: 'C:\WINDOWS\system32\cmd.exe' : return code '0x1'
Stop.
NMAKE : fatal error U1077: 'C:\WINDOWS\system32\cmd.exe' : return code '0x2'
Stop.
  MLEHMANN/Coro-5.372.tar.gz
  nmake -- NOT OK
Running make test
  Can't test without successful make
Running make install
  Make had returned bad status, install seems impossible
Failed during this command:
 MLEHMANN/Guard-1.021.tar.gz                  : make NO
 MLEHMANN/Coro-5.372.tar.gz                   : make NO



Это сообщение отредактировал(а) alezzz - 20.5.2011, 13:45
PM MAIL   Вверх
Pfailed
Дата 20.5.2011, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 1
Всего: 39



Что мешает сделать cl алиасом gcc?

Добавлено через 4 минуты и 16 секунд
А что у вас с ppm? Тут написано, что на 32 битной всё работает: http://code.activestate.com/ppm/Coro/


--------------------
PM MAIL   Вверх
alezzz
Дата 20.5.2011, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: нет
Всего: 14



Незнаю, с ppm ничего не делал. Кроме перла ничего другого нет, gcc тоже надо поискать. Такое с ppm вообще бывает редко, кроме Coro кажется был только один такой-же случай, только не помню уже с каким модулем.
PM MAIL   Вверх
shamber
Дата 20.5.2011, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1422
Регистрация: 5.9.2006
Где: Россия

Репутация: нет
Всего: 18



Код

Installing Coro (5.372)
Running [C:\Perl\bin\perl.exe C:\Perl\site\bin\cpanp-run-perl C:\DOCUME~1\Admin\
APPLIC~1\CPANPL~1\510~1.1\build\Coro-5.372\Makefile.PL]...
Set up gcc environment - 3.4.5 (mingw-vista special r3)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***


*** Event not found, not build Event support.


*** EV not found, not build EV support.

Checking if your kit is complete...
Looks good
Warning: prerequisite Guard 0.5 not found.

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Coro has a number of configuration options. Due to its maturity, the
defaults that Coro chooses are usually fine, so you can decide to skip
these questions. Only if something went wrong you should select 'n'
here and manually configure Coro, and, of course, report this to the
maintainer :)

Skip further questions and use defaults (y/n)? [y]

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Coro can use a number of methods to implement coroutines at the C
level. The default chosen is based on your current confguration and is
correct in most cases, but you still can chose between these alternatives:

u  The unix 'ucontext.h' functions are relatively new and not implemented
   or well-tested in older unices. They allow very fast coroutine creation
   and reasonably fast switching.  They are, however, usually slower than
   the other alternatives due to an extra syscall done by swapcontext. And
   while nominally most portable (it's the only POSIX-standardised
   interface for coroutines), ucontext functions are, as usual, broken on
   most/all BSDs.

s  If the ucontext functions are not working or you don't want
   to use them for other reasons you can try a workaround using
   setjmp/longjmp/sigaltstack (also standard unix functions). Coroutine
   creation is rather slow, but switching is very fast (often much faster
   than with the ucontext functions). Unfortunately, glibc-2.1 and
   below don't even feature a working sigaltstack. You cannot use this
   implementation if some other code uses SIGUSR2 or you plan to create
   coroutines from an alternative signal stack, as both are being used for
   coroutine creation.

a  Handcoded assembly. This is the fastest and most compatible method,
   with the least side effects, if it works, that is. It has been tested
   on GNU/Linux x86 and x86_64 systems and should work on all x86/x86_64
   systems using the SVR ELF ABI (it is also reported to be working on
   Strawberry Perl for Windows using MinGW). This is the recommended
   method on supported platforms. When it doesn't work, use another
   method, such as (s)etjmp/longjmp.

l  GNU/Linux. Very old GNU/Linux systems (glibc-2.1 and below) need
   this hack. Since it is very linux-specific it is also quite fast and
   recommended even for newer versions; when it works, that is (currently
   x86 and a few others only. If it compiles, it's usually ok). Newer
   glibc versions (>= 2.5) stop working with this implementation however.

i  IRIX. For some reason, SGI really does not like to follow POSIX (does
   that surprise you?), so this workaround might be needed (it's fast),
   although [s] and [u] should also work now.

w  Microsoft Windows. Try this on Microsoft Windows when using Cygwin or
   the MSVC compilers (e.g. ActiveState Perl, but see "a" for Strawberry
   Perl), although, as there is no standard on how to do this under
   windows, different environments might work differently. Doh.

p  Use pthread API. Try to avoid this option, it was only created to
   make a point about the programming language shootout. It is unlikely
   to work with perls that have windows process emulation enabled ("perl
   threads"). It is also likely the slowest method of implementing
   coroutines. It might work fine as a last resort, however, as the
   pthread API is slightly better tested than ucontext functions for
   example. Of course, not on BSDs, who usually have very broken pthread
   implementations.

Coro tries hard to come up with a suitable default for most systems,
so pressing return at the prompt usually does the right thing. If you
experience problems (e.g. make test fails) then you should experiment with
this setting.

Use which implementation,
<s>etjmp, <u>ctx, <a>sm, <i>rix, <l>inux, <w>indows or <p>threads? [w] w

Using windows-specific implementation


*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Per-context stack size factor: Depending on your settings, Coro tries to
share the C stacks is creates as much as possible, but sometimes it needs
to allocate a new one. This setting controls the maximum size that gets
allocated, and should not be set too high, as memory and address space
still is wasted even if it's not fully used. The value entered will be
multiplied by sizeof(long), which is usually 4 on 32-bit systems, and 8 on
64-bit systems.

A setting of 16384 (the default) therefore corresponds to a 64k..128k
stack, which usually is ample space (you might even want to try 8192 or
lower if your program creates many coroutines).

On systems supporting mmap and dynamic memory management, the actual
memory usually gets allocated on demand, but with many large stacks you
can still run out of address space on your typical 32 bit platform (not to
forget the pagetables).

Some perls (mostly threaded ones and perl compiled under linux 2.6) and
some programs (inefficient regexes can use a lot of stack space) may
need much, much more: If Coro segfaults with weird backtraces (e.g. in a
function prologue) or in t/10_bugs.t, you might want to increase this to
65536 or more.

The default should be fine, and can be changed at runtime with
Coro::State::cctx_stacksize.

C stack size factor? [16384] 16384
using a stacksize of 16384 * sizeof(long)

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Coro can optionally put a guard area before each stack segment: When the
stack is too small and the access is not too far outside the stack (i.e.
within the guard area), then the program will safely segfault instead of
running into other data. The cost is some additional overhead with is
usually negligible, and extra use of address space.

The guard area size currently needs to be specified in pages (typical
pagesizes are 4k and 8k). The guard area is only enabled on a few
hardcoded architectures and is ignored on others. The actual preprocessor
expression disables this feature if:

   !__i386 && !__x86_64 && !__powerpc && !__m68k
   && !__alpha && !__mips && !__sparc64

The default, as usual, should be just fine.

Number of guard pages (0 disables)? [4] 4

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Coro can tell valgrind about its stacks and so reduce spurious warnings
where valgrind would otherwise complain about possible stack switches.

Enabling this does not incur noticable runtime or memory overhead, but it
requires that you have the <valgrind/valgrind.h> header file available.

Valgrind support is completely optional, so disabling it is the safe
choice.

Enable valgrind support (y/n)? [n] n

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Coro can use (or even trick) some perl functions into doing what it needs
instead of relying on (some) of its own functions. This might increase
chances that it compiles and works, but it could just as well result in
memory leaks, crashes or silent data corruption. It certainly does result
in slightly slower speed and higher memory consumption, though, so YOU
SHOULD ENABLE THIS OPTION ONLY AS A LAST RESORT.

Prefer perl functions over coro functions (y/n)? [n] n

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Coro has experimental support for cloning states. This can be used
to implement a scheme-like call/cc. However, this doesn't add to the
expressiveness in general, and is likely perl-version specific (and perl
5.12 deliberately removed support for it). As such, it is disabled by
default.  Enable it when you want to play around with it, but note that it
isn't supported, and unlikely ever will be. It exists mainly to prove that
it could be done - if only it were useful for something.

Implement Coro::State->clone method (y/n)? [n] n

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

Writing Makefile for Coro::State
Writing Makefile for Coro

Module 'Coro' requires 'Guard' to be installed

If you don't wish to see this question anymore
you can disable it by entering the following commands on the prompt:
    's conf prereqs 1; s save'


  1> Yes
  2> No
  3> Yes to all (for this module)
  4> No to all  (for this module)

Should I install this module? [1]: 3
[ERROR] Could not read C:\DOCUME~1\Admin\APPLIC~1\CPANPL~1\510~1.1\build\Guard-1
.021\META.yml: 'Parse::CPAN::Meta failed to classify line '{' at C:/Perl/site/li
b/CPANPLUS/Dist.pm line 365
'

Running [C:\Perl\bin\perl.exe C:\Perl\site\bin\cpanp-run-perl C:\DOCUME~1\Admin\
APPLIC~1\CPANPL~1\510~1.1\build\Guard-1.021\Makefile.PL]...
Set up gcc environment - 3.4.5 (mingw-vista special r3)
Checking if your kit is complete...
Looks good
Writing Makefile for Guard
Running [C:\Perl\site\bin\dmake.exe test]...
C:\Perl\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib\lib',
 'blib\arch')" t/*.t
t/00_load.t .... ok
t/01_scoped.t .. ok
t/02_guard.t ... ok
t/03_die.t ..... ok
All tests successful.
Files=4, Tests=33,  0 wallclock secs ( 0.03 usr +  0.05 sys =  0.08 CPU)
Result: PASS
Running [C:\Perl\site\bin\dmake.exe test]...
C:\Perl\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib\lib',
 'blib\arch')" t/*.t
t/00_basic.t ...... ok
t/01_process.t .... ok
t/02_channel.t .... ok
t/03_channel.t .... ok
t/04_rwlock.t ..... ok
t/05_specific.t ... ok
t/06_prio.t ....... ok
t/07_eval.t ....... ok
t/08_join.t ....... ok
t/10_bugs.t ....... ok
t/11_deadlock.t ... skipped: (no reason given)
t/12_exit.t ....... skipped: (no reason given)
t/13_diewarn.t .... ok
t/14_load.t ....... ok
t/15_semaphore.t .. ok
t/16_signal.t ..... ok
t/17_rouse.t ...... ok
t/18_winder.t ..... ok
t/19_handle.t ..... skipped: Broken perl detected, skipping tests.
All tests successful.
Files=19, Tests=172,  3 wallclock secs ( 0.16 usr +  0.05 sys =  0.20 CPU)
Result: PASS
'No tests defined for Coro::State extension.'
*** Install log written to:
  C:\Documents and Settings\Admin\Application Data\.cpanplus\install-logs\Coro-5
.372-1305902908.log

Module 'Coro' installed successfully
No errors installing all modules

Windows XP mingw perl 5.10

Добавлено через 3 минуты и 38 секунд

1. Для этого качаете mingw и устанавливаете его. после установки вам нужно добавить его в PATH.
2. Cкачиваете dmake. Разархивируете его куда нибудь и добавляете эту папку в PATH

3.Скачиваете модуль ExtUtils-FakeConfig и устанавливаете его.
PM MAIL Jabber   Вверх
Pfailed
Дата 20.5.2011, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 1
Всего: 39



Один фиг мой пример в винде не завёлся, у меня по крайней мере. Почему-то LWP не хочет качать а параллель.



--------------------
PM MAIL   Вверх
shamber
Дата 20.5.2011, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1422
Регистрация: 5.9.2006
Где: Россия

Репутация: нет
Всего: 18



Код

"cl" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.

 значит нет компимлятора
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: GUI | Следующая тема »


 




[ Время генерации скрипта: 0.0898 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.