ファイバつかってみる。

関数の途中で戻って再開出来るとか、C言語コードだけ見てたらとても奇妙な冒険。

#include "stdafx.h"

#include <Windows.h>

const int LOOP_COUNT_IN_MAIN = 5;
const int LOOP_COUNT_IN_FIBER = 5;

PVOID pMainFiber;
PVOID pFibers[4];

struct DestroyChecker
{
	~DestroyChecker()
	{
		printf("Fiber[%p]: Destroyed.\n");
	}
};

VOID WINAPI FiberFunc(PVOID pvParam)
{
	DestroyChecker d;

	for (int i = 0; i < LOOP_COUNT_IN_FIBER; ++i)
	{
		printf("Fiber[%p]: %d (%x)\n", GetCurrentFiber(), i, GetCurrentThreadId());
		SwitchToFiber(pMainFiber);
	}
	// ココに来ちゃうとスレッド自体が終わっちゃう
}

int _tmain(int argc, _TCHAR* argv[])
{
	pMainFiber = ConvertThreadToFiber(NULL);
	
	for (int i = 0; i < _countof(pFibers); ++i)
	{
		pFibers[i] = CreateFiber(0, FiberFunc, NULL);
	}

	for (int i = 0; i < LOOP_COUNT_IN_MAIN; ++i)
	{
		for (int k = 0; k < _countof(pFibers); ++k)
		{
			SwitchToFiber(pFibers[k]);
		}
	}

	for (int i = 0; i < _countof(pFibers); ++i)
	{
		DeleteFiber(pFibers[i]);
	}

	ConvertFiberToThread();

	printf("End.\n");

	return 0;
}

結果はこんなん。

Fiber[00401BD8]: 0 (149c)
Fiber[00401EF8]: 0 (149c)
Fiber[00402218]: 0 (149c)
Fiber[00402538]: 0 (149c)
Fiber[00401BD8]: 1 (149c)
Fiber[00401EF8]: 1 (149c)
Fiber[00402218]: 1 (149c)
Fiber[00402538]: 1 (149c)
Fiber[00401BD8]: 2 (149c)
Fiber[00401EF8]: 2 (149c)
Fiber[00402218]: 2 (149c)
Fiber[00402538]: 2 (149c)
Fiber[00401BD8]: 3 (149c)
Fiber[00401EF8]: 3 (149c)
Fiber[00402218]: 3 (149c)
Fiber[00402538]: 3 (149c)
Fiber[00401BD8]: 4 (149c)
Fiber[00401EF8]: 4 (149c)
Fiber[00402218]: 4 (149c)
Fiber[00402538]: 4 (149c)
End.

案の定デストラクタは動いてない。


ファイバ関数から戻らせてみると

const int LOOP_COUNT_IN_FIBER = 2;
Fiber[00361BD8]: 0 (1790)
Fiber[00361EF8]: 0 (1790)
Fiber[00362218]: 0 (1790)
Fiber[00362538]: 0 (1790)
Fiber[00361BD8]: 1 (1790)
Fiber[00361EF8]: 1 (1790)
Fiber[00362218]: 1 (1790)
Fiber[00362538]: 1 (1790)
Fiber[0073FF4C]: Destroyed.

一個だけデストラクタが動いて、スレッドが終了してプロセスが終了した。
ADVANCED WINDOWS 第5版 上 (マイクロソフト公式解説書)の通りだた!