Потоки в перле изнутри
Upcoming SlideShare
Loading in...5
×
 

Потоки в перле изнутри

on

  • 803 views

Продолжение серии докладов "Perl изнутри". На этот раз будут рассмотрены потоки.

Продолжение серии докладов "Perl изнутри". На этот раз будут рассмотрены потоки.

Statistics

Views

Total Views
803
Views on SlideShare
803
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Потоки в перле изнутри Потоки в перле изнутри Presentation Transcript

    • ПОТОКИ В PERLСамунь Виктор
    • Зачем изучать?• Механизмы работы• Оптимальное использование• Это интересно• Поиск ошибок
    • Способы изученияЧитать/модифицировать исходникиИсходники: http://www.cpan.org/src/README.html
    • Структура исходников• Корень: • sv.h av.h hv.h gv.h perl.h … • sv.c av.c hv.c gv.c perl.c malloc.c … • beos/ haiku/ os2/ plan9/ qnx/ win32/ …• win32/ • perlmain.c • Makefile • win32thread.c …
    • pp_sys.cPP(pp_fork){#ifdef HAS_FORK dVAR; dSP; dTARGET; Pid_t childpid; EXTEND(SP, 1); PERL_FLUSHALL_FOR_CHILD; childpid = PerlProc_fork(); if (childpid < 0) RETSETUNDEF; if (!childpid) { GV * const tmpgv = gv_fetchpvs("$", GV_ADD|GV_NOTQUAL, SVt_PV); if (tmpgv) { SvREADONLY_off(GvSV(tmpgv)); sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid()); SvREADONLY_on(GvSV(tmpgv)); }...
    • win32win32thread.h#ifndef DONT_USE_CRITICAL_SECTION/* Critical Sections used instead of mutexes:lightweight, * but cant be communicated to child processes, andcant get * HANDLE to it for use elsewhere. */typedef CRITICAL_SECTION perl_mutex;#define MUTEX_INIT(m) InitializeCriticalSection(m)#define MUTEX_LOCK(m) EnterCriticalSection(m)#define MUTEX_UNLOCK(m) LeaveCriticalSection(m)#define MUTEX_DESTROY(m) DeleteCriticalSection(m)#else...
    • win32win32thread.h...typedef HANDLE perl_mutex;# define MUTEX_INIT(m) STMT_START { if ((*(m) = CreateMutex(NULL,FALSE,NULL)) == NULL) Perl_croak_nocontext("panic: MUTEX_INIT"); } STMT_END# define MUTEX_LOCK(m) STMT_START { if (WaitForSingleObject(*(m),INFINITE) == WAIT_FAILED) Perl_croak_nocontext("panic: MUTEX_LOCK"); } STMT_END# define MUTEX_UNLOCK(m) STMT_START { if (ReleaseMutex(*(m)) == 0) Perl_croak_nocontext("panic: MUTEX_UNLOCK"); } STMT_END# define MUTEX_DESTROY(m) STMT_START { if (CloseHandle(*(m)) == 0) Perl_croak_nocontext("panic: MUTEX_DESTROY"); } STMT_END
    • win32win32thread.h#if defined(USE_RTL_THREAD_API) && !defined(_MSC_VER)#define JOIN(t, avp) STMT_START { if ((WaitForSingleObject((t)->self,INFINITE) == WAIT_FAILED) || (GetExitCodeThread((t)->self,(LPDWORD)(avp)) == 0) || (CloseHandle((t)->self) == 0)) Perl_croak_nocontext("panic: JOIN"); *avp = (AV *)((t)->i.retv); } STMT_END#else /* !USE_RTL_THREAD_API || _MSC_VER */#define JOIN(t, avp) STMT_START { if ((WaitForSingleObject((t)->self,INFINITE) == WAIT_FAILED) || (GetExitCodeThread((t)->self,(LPDWORD)(avp)) == 0) || (CloseHandle((t)->self) == 0)) Perl_croak_nocontext("panic: JOIN"); } STMT_END#endif /* !USE_RTL_THREAD_API || _MSC_VER */#define YIELD Sleep(0)
    • win32perlhost.hintPerlProcFork(struct IPerlProc* piPerl){ dTHX;#ifdef USE_ITHREADS DWORD id; HANDLE handle; CPerlHost *h; if (w32_num_pseudo_children >= MAXIMUM_WAIT_OBJECTS) { errno = EAGAIN; return -1; } h = new CPerlHost(*(CPerlHost*)w32_internal_host); PerlInterpreter *new_perl = perl_clone_using((PerlInterpreter*)aTHX, CLONEf_COPY_STACKS, h->m_pHostperlMem, h->m_pHostperlMemShared, h->m_pHostperlMemParse, h->m_pHostperlEnv, h->m_pHostperlStdIO, h->m_pHostperlLIO, h->m_pHostperlDir, h->m_pHostperlSock, h->m_pHostperlProc );
    • win32perlhost.h new_perl->Isys_intern.internal_host = h; h->host_perl = new_perl;# ifdef PERL_SYNC_FORK id = win32_start_child((LPVOID)new_perl); PERL_SET_THX(aTHX);# else if (w32_message_hwnd == INVALID_HANDLE_VALUE) w32_message_hwnd = win32_create_message_window(); new_perl->Isys_intern.message_hwnd = w32_message_hwnd; w32_pseudo_child_message_hwnds[w32_num_pseudo_children] = (w32_message_hwnd == NULL) ? (HWND)NULL : (HWND)INVALID_HANDLE_VALUE;# ifdef USE_RTL_THREAD_API handle = (HANDLE)_beginthreadex((void*)NULL, 0, win32_start_child, (void*)new_perl, 0, (unsigned*)&id);# else handle = CreateThread(NULL, 0, win32_start_child, (LPVOID)new_perl, 0, &id);# endif
    • win32perlhost.h PERL_SET_THX(aTHX); /* XXX perl_clone*() set TLS */ if (!handle) { errno = EAGAIN; return -1; } if (IsWin95()) { int pid = (int)id; if (pid < 0) id = -pid; } w32_pseudo_child_handles[w32_num_pseudo_children] = handle; w32_pseudo_child_pids[w32_num_pseudo_children] = id; ++w32_num_pseudo_children;# endif return -(int)id;#else Perl_croak(aTHX_ "fork() not implemented!n"); return -1;#endif /* USE_ITHREADS */
    • win32perlhost.hCPerlHost::CPerlHost(CPerlHost& host){ /* Construct a host from another host */ InterlockedIncrement(&num_hosts); m_pVMem = new VMem(); m_pVMemShared = host.GetMemShared(); m_pVMemParse = host.GetMemParse(); /* duplicate directory info */ m_pvDir = new VDir(0); m_pvDir->Init(host.GetDir(), m_pVMem);
    • win32perlhost.hCopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));CopyMemory(&m_hostperlMemShared, &perlMemShared,sizeof(perlMemShared));CopyMemory(&m_hostperlMemParse, &perlMemParse,sizeof(perlMemParse));CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));CopyMemory(&m_hostperlStdIO, &perlStdIO,sizeof(perlStdIO));CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));...
    • Спасибо за внимание! Вопросы?