Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 115 стр.

UptoLike

for ( i = 0; i < FIBERS;) {
SwitchToFiber( fiber[i] );
if ( fiberEnd ) {
DeleteFiber(fiberEnd );
for ( i = 0; i < FIBERS; i++ ) {
if ( fiber[i] == fiberEnd ) fiber[i] = NULL;
}
fiberEnd = NULL;
}
for ( i = 0; i < FIBERS; i++ ) if ( fiber[i] ) break;
}
ConvertFiberToThread();
return 0;
}
Следует еще раз отметить одну важную особенность волокон – они
работают в рамках одного потока и не позволяют задействовать возможно-
сти мультипроцессирования. Если нужно обеспечить параллельное ис-
полнение кода на разных процессорах, то надо применять потоки либо да-
же отдельные процессы. В частных случаях возможно создание гибридных
вариантов – когда несколько потоков выполняют несколько волокон; при
этом число волокон может существенно превышать число потоков. Одна-
ко и в этом случае целесообразность применения волокон должна быть
тщательно изучена: очень часто эффективнее не выполнять одновременно
много мелких заданий, а выполнять их поочередно – тогда уменьшатся за-
траты на переключения и, возможно, возрастет утилизация кэша. Волок-
на представляют, по большей части, теоретический интерес, как возмож-
ность реализовать планировщик пользовательского режима, помимо су-
ществующего стандартного планировщика режима ядра.
Основы многозадачности
217
#define _WIN32_WINNT 0x0400
#include <windows.h>
#define FIBERS 2
static LPVOID fiberEnd;
static LPVOID fiberCtl;
static LPVOID fiber[ FIBERS ];
static void shedule( BOOL fDontEnd )
{
int n, current;
if ( !fDontEnd ) { /* волокно надо завершить */
fiberEnd = GetCurrentFiber();
SwitchToFiber(fiberCtl );
}
/* выбираем следующее волокно для выполнения */
for ( n = 0; n < FIBERS; n++ ) {
if ( fiber[n] && fiber[n] != GetCurrentFiber() ) break;
}
if ( n >= FIBERS ) return; /* нет других готовых волокон*/
SwitchToFiber( fiber[n] );
}
VOID CALLBACK FiberProc( PVOID lpParameter )
{ /* волокно будет выполнять код этой функции */
int i;
for ( i = 0; i < 100; i++ ) {
Sleep( 1000 );
shedule( TRUE ); /* выполнение продолжается */
}
shedule( FALSE ); /* волокно завершается */
}
int main( void )
{
int i;
fiberCtl = ConvertThreadToFiber( NULL );
fiberEnd = NULL;
for ( i = 0; i < FIBERS; i++ ) {
fiber[i] = CreateFiber( 10000, FiberProc, NULL );
}
216
CIL и системное программирование в Microsoft .NET
216                          CIL и системное программирование в Microsoft .NET   Основы многозадачности                                             217


      #define _WIN32_WINNT 0x0400                                                         for ( i = 0; i < FIBERS;) {
      #include                                                                   SwitchToFiber( fiber[i] );
                                                                                            if ( fiberEnd ) {
      #define FIBERS 2                                                                        DeleteFiber(fiberEnd );
                                                                                              for ( i = 0; i < FIBERS; i++ ) {
      static LPVOID   fiberEnd;                                                                 if ( fiber[i] == fiberEnd ) fiber[i] = NULL;
      static LPVOID   fiberCtl;                                                               }
      static LPVOID   fiber[ FIBERS ];                                                        fiberEnd = NULL;
                                                                                            }
      static void shedule( BOOL fDontEnd )                                                  for ( i = 0; i < FIBERS; i++ ) if ( fiber[i] ) break;
      {                                                                                   }
        int      n, current;                                                              ConvertFiberToThread();
        if ( !fDontEnd ) { /* волокно надо завершить */                                   return 0;
          fiberEnd = GetCurrentFiber();                                               }
          SwitchToFiber(fiberCtl );
        }                                                                             Следует еще раз отметить одну важную особенность волокон – они
        /* выбираем следующее волокно для выполнения */                          работают в рамках одного потока и не позволяют задействовать возможно-
        for ( n = 0; n < FIBERS; n++ ) {                                         сти мультипроцессирования. Если нужно обеспечить параллельное ис-
          if ( fiber[n] && fiber[n] != GetCurrentFiber() ) break;                полнение кода на разных процессорах, то надо применять потоки либо да-
        }                                                                        же отдельные процессы. В частных случаях возможно создание гибридных
        if ( n >= FIBERS ) return; /* нет других готовых волокон*/               вариантов – когда несколько потоков выполняют несколько волокон; при
        SwitchToFiber( fiber[n] );                                               этом число волокон может существенно превышать число потоков. Одна-
      }                                                                          ко и в этом случае целесообразность применения волокон должна быть
                                                                                 тщательно изучена: очень часто эффективнее не выполнять одновременно
      VOID CALLBACK FiberProc( PVOID lpParameter )                               много мелких заданий, а выполнять их поочередно – тогда уменьшатся за-
      { /* волокно будет выполнять код этой функции */                           траты на переключения и, возможно, возрастет утилизация кэша. Волок-
        int i;                                                                   на представляют, по большей части, теоретический интерес, как возмож-
        for ( i = 0; i < 100; i++ ) {                                            ность реализовать планировщик пользовательского режима, помимо су-
          Sleep( 1000 );                                                         ществующего стандартного планировщика режима ядра.
          shedule( TRUE ); /* выполнение продолжается */
        }
        shedule( FALSE ); /* волокно завершается */
      }

      int main( void )
      {
        int i;
        fiberCtl = ConvertThreadToFiber( NULL );
        fiberEnd = NULL;
        for ( i = 0; i < FIBERS; i++ ) {
          fiber[i] = CreateFiber( 10000, FiberProc, NULL );
        }