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

788 views

Published on

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

Published in: Education, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
788
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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

  1. 1. ПОТОКИ В PERLСамунь Виктор
  2. 2. Зачем изучать?• Механизмы работы• Оптимальное использование• Это интересно• Поиск ошибок
  3. 3. Способы изученияЧитать/модифицировать исходникиИсходники: http://www.cpan.org/src/README.html
  4. 4. Структура исходников• Корень: • 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 …
  5. 5. 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)); }...
  6. 6. 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...
  7. 7. 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
  8. 8. 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)
  9. 9. 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 );
  10. 10. 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
  11. 11. 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 */
  12. 12. 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);
  13. 13. 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));...
  14. 14. Спасибо за внимание! Вопросы?

×