�������� Linux Tags

20. �๤�Ͷ�ִ����

�๤��һ����ҵϵͳ����ͬʱִ�ж����ʽ�������������ϣ���ҵϵͳʹ��һ��Ӳ��ʱ��Ϊͬʱִ�е�ÿ���������á�ʱ��Ƭ�Ρ������ʱ��Ƭ�ι�С�����һ���Ҳû�����̫��ij�ʽ����������ʱ����ô��ʹ���߿��������е���Щ��ʽ�ƺ���ͬʱִ������

�๤������ʲô�µĶ������ڴ��͵����ϣ��๤�DZ�Ȼ�ġ���Щ��������ͨ���м�ʮ�������ٸ��ն˻��������ᣬ��ÿ���ն˻�ʹ���߶�Ӧ�øо�������������ռ���������ԡ����⣬������������ҵϵͳͨ������ʹ���ߡ��ύ����������������Щ������ҵ������ʹ���߽�����������ʱ���ɻ���ִ����ɡ�

���˵����ϵĶ๤���˸�����ʱ����ռ�������������PC�๤Ҳ����Ϊ�Ǻ��������ˡ������Ͼͻ����۵���Microsoft Windows��16λԪ�汾֧Ԯ���޶ȵĶ๤��Windows��32λԪ�汾֧Ԯ�����Ķ๤�����ң�������һ�ֶ�����ŵ㣬��ִ������

��ִ��������һ����ʽ�ڲ�ʵ���๤����������ʽ���԰����Լ��ָ�Ϊ���Զ����ġ�ִ����������Щִ�����ƺ�Ҳͬʱ��ִ��������һ������������ƺ�û��ʲô�ô��������������ó�ʽʹ�ö�ִ�����ڱ���ִ���߳���ҵ���Ӷ���ʹ���߲��س�ʱ����޷�ʹ������Խ���������������ʱ��Ҳ������������ϣ���ģ���������ʱ��ȥ��������ߵ�����ȥ�������Ǻܲ����ģ������ǣ���ʹ�ڵ��Է�æ��ʱ��ʹ����ҲӦ���ܹ�ʹ������

�๤�ĸ���ģʽ
��

��PC�����ڣ����������ᳫδ��Ӧ�ó��๤�ķ���ǰ�������Ǵ�������˻��Ǻ��Ի���һ����ʹ���ߵĸ��˵����ϣ��๤��ʲô���أ����ˣ�������ʵ��ʾ��ʹ�Dz�֪����һ�����ʹ����Ҳ����Ҫ�๤�ġ�

DOS�µĶ๤
��

�����PC�ϵ�Intel 8088΢������������Ϊ�๤����Ƶġ�����ԭ��������һ�������۹����Ǽ������������ǿ���������ͽ��������ʽʱ���๤����ҵϵͳͨ����Ҫ�ƶ�����������ռ����м����塣��8088���Dz�����͸���Ӧ��ϵͳ��������һ��ġ�

DOS�����Զ๤û��̫��İ������������Ŀ���Ǿ�����С�ɣ�����������Ӧ�ó�ʽ֮�⣬��ˣ����������ʽ�Լ��Գ�ʽ�ṩ����ϵͳ�Ĵ�ȡ���ܣ�������û���ṩ�κ�֧Ԯ��

�������д���ij�ʽд������Ȼ��DOS�����ھ��ҵ���һ�ֿ˷���Щȱ�ݵķ������������ʹ�ó�פ��TSR��terminate-and-stay-resident����ʽ����ЩTSR�����米����ӡ���г�ʽ�ȣ�͸������Ӳ��ʱ���ж���ִ�������ı���������������TSR������SideKick��ͻ��ʽ���ߣ�����ִ��ij����̬�Ĺ����л�����ͣĿǰ��Ӧ�ó�ʽ��ִ��ͻ��ʽ���ߡ�DOSҲ��������ǿ�Ա��ṩ��TSR��֧Ԯ��

һЩ���峧����ͼ��DOS֮�ϼܹ��������л����߶๤����dz�ʽ��shell��������Quarterdeck��DesqView������������Щ�����У���������һ��ռ���˴󲿷��г�����Ȼ�������Windows��

������Ȩʽ�Ķ๤
��

��Microsoft��1985�귢��Windows 1.0ʱ�����������Ľ��������Ŀ����ͻ��DOS�ľ��ޡ�Windows��ʵ��ģʽ��ִ�С����Ǽ�ʹ���������ѿ�����ʵ����������ƶ�������顣���Ƕ๤��ǰ�ᣬ��Ȼ�ƶ��ķ�����δ��ȫ͸���Ӧ�ó�ʽ�����Ǽ������������ˡ�

��ͼ���Ӵ������У��๤����һ�������е�ʹ������ҵϵͳ���Եø������塣���磬�ڴ�ͳ��������UNIX�У�������������֮��ִ�г�ʽ���������ڱ���ִ�С�Ȼ������ʽ��������ʾ������뱻����ת��һ�������У������������ʹ�������������������һ��

�Ӵ��������������ʽ����ͬөĻ��һ��ִ�У�ǰ���л��dz����ף����һ����Կ��ٵؽ����ϴ�һ����ʽ�ƶ�����һ����ʽ�С����磬����ͼ��ʽ�н�����ͼƬǶ�������鴦����ʽ�༭�����ֵ����С���Windows�У��Զ��ַ�ʽ֧Ԯ����ת�ƣ�������ʹ�ü�������������ʹ�ö�̬���Ͻ�����DDE��������������͸����������Ƕ�루OLE����

����������Windows�Ķ๤ʵ�������Ƕ�ʹ������ҵϵͳ�д�ͳ������Ȩʽ�ķ�ʱ�๤����Щ��ҵϵͳʹ��ϵͳʱ�������Ե��ж�һ����������ʼ��һ��������Windows����Щ16λԪ�汾֧Ԯһ�ֱ���Ϊ��������Ȩʽ�Ķ๤�������WindowsѶϢ�����ļܹ���ʹ������̬�Ķ๤��Ϊ���ܡ�ͨ������£�һ��Windows��ʽ���ڼ�������˯�ߣ�ֱ�����յ�һ��ѶϢΪֹ����ЩѶϢͨ����ʹ���ߵļ��̻��������ֱ�ӻ��ӽ������������ѶϢ֮�ᣬ��ʽ������Ȩ���ظ�Windows��

Windows��16λԪ�汾������Ե�����һ��timer tick������Ȩ��һ��Windows��ʽ�л�����һ�����κεĹ����л��������ڵ���ʽ��ɶ�ѶϢ�Ĵ����Ὣ����Ȩ���ظ�Windowsʱ�����ַ�����Ȩʽ�Ķ๤Ҳ����Ϊ������ʽ�Ķ๤������Ϊ��Ҫ������Ӧ�ó�ʽ�����һЩ������һ��Windows��ʽ����ռ������ϵͳ�������Ҫ���ܳ�һ��ʱ��������ѶϢ�Ļ���

��Ȼ������Ȩʽ�Ķ๤��16λԪWindows��һ����򣬵���Ȼ������ijЩ��ʽ������Ȩʽ�๤��Windowsʹ������Ȩʽ�๤��ִ��DOS��ʽ�����ң�Ϊ��ʵ����ý�壬��������̬�����ʽ�����Ӳ��ʱ���жϡ�

16λԪWindows������������������������ʽд���߽�������ߣ����ٿ���˵�ǶԸ���������Ȩʽ�๤�еľ��ޣ��������ĵ�Ȼ��ʱ��ʽ�����αꡣ��Ȼ���Ⲣ��һ�ֽ������������������ʹ����֪��һ����ʽ����æ춴���һ���߳���ҵ�������ʹ������һ��ʱ�����޷�ʹ��ϵͳ����һ�ֽ��������Windows��ʱ������������ʽ�����Եؽ���ѶϢ�����һЩ��������ʱ��ͨ�����ʱ��Ӧ�úͶ�����

��Է�����Ȩʽ�๤����һ�ֽ��������PeekMessage��ʽ���У��������ڵ������е�RANDRECT��ʽ�￴������һ����ʽͨ��ʹ��GetMessage���д�����ѶϢ��������Ѱ��һ��ѶϢ�������������ѶϢ������û��ѶϢ����ôGetMessage���ᴫ�أ�һֱ������һ��ѶϢΪֹ������һ���棬PeekMessage������Ȩ���س�ʽ����ʹû�еȴ���ѶϢ��������һ����ʽ����ִ��һ���߳���ҵ�����ڳ�ʽ���л���PeekMessage���С�ֻҪû�������ʽ�������κγ�ʽ��ѶϢҪ��������ô����߳���ҵ������ִ�С�

Presentation Manager�����л���ѶϢ����
��

Microsoft��һ�ְ�DOS/��Windows�Ļ�����ʵ���๤�ĵ�һ�����ԣ���IBM��������OS/2��Presentation Manager����д��PM )����ȻOS/2��ȷ��֧Ԯ����Ȩʽ�๤���������ֶ๤��ʽ�ƺ���δ��Presentation Manager�е�����ʵ���������PM���л����Լ��̺ͻ����ʹ��������ѶϢ������ζ������ǰһ��ʹ��������ѶϢ����ȫ������ǰ��PM���Ὣһ�����̻��߻���ѶϢ���͸���ʽ��

���ܼ��̺ͻ���ѶϢֻ��һ��PM������Windows����ʽ���Խ��յ�����ѶϢ�еļ����������������ѶϢ���Ǽ��̻��߻����¼��Ľ�������磬���ܱ�����ѶϢ��ʹ����ʹ�ü��̻��߻�����й��ܱ�ѡ��Ľ�����ڴ������ܱ�����ѶϢʱ�����̻��߻���ѶϢ��δ��ȫ��������

���л�ѶϢ���е���Ҫԭ��������ʹ���ߵ�Ԥ�ȡ����롹���̰�����Ԥ�ȡ����롹����ť�����һ�����̻��߻���ѶϢ�������뽹���һ���Ӵ��л�����һ���Ӵ�����ô�������ļ���ѶϢӦ�ý���ӵ���µ����뽹����Ӵ���ȥ����ˣ�ϵͳ��֪������һ��ʹ��������ѶϢ���͵��δ���ֱ��ǰһ��ѶϢ��������Ϊֹ��

Ŀǰ�Ĺ�ʶ�Dz�Ӧ����һ��Ӧ��ϵͳ�п���ռ������ϵͳ��������Ҫ�����л���ѶϢ���У�32λԪ�汾��Windows֧Ԯ����ѶϢ���С����һ����ʽ����æ������һ���߳���ҵ����ô�����Խ����뽹���л�����һ����ʽ�С�

��ִ�����������
��

������OS/2��Presentation Manager��ֻ����Ϊ���ǵ�һ��Ϊ���ڵ�Windows��ʽд���ߣ��������Լ������ܶ�ִ�����Ļ�������Ȥ���ǣ�PMʵ����ִ�����ľ���Ϊ��ʽд�����ṩ��Ӧ����μܹ���ִ������ʽ�ı�Ҫ��������ʹ��Щ������32λԪ��Windows���Ѿ�������٣����ǴӸ����޵Ļ�����ѧ���ľ�����Ȼ�Ƿdz���Ч�ġ���ˣ������Ǽ���������ȥ��

��һ����ִ���������У���ʽ���Խ������Լ��ָ�Ϊͬʱִ�е�Ƭ�Σ�����ִ����������ִ������֧Ԯ�ǽ��PM�д��ڵ����л�ѶϢ���е���÷�����������Windows��ִ�����и�ʵ�ʵ����塣

�ͳ�ʽ����˵��һ��ִ�����򵥵ر���ʾΪ���ܺ��г�ʽ��������ʽ�ĺ�ʽ����ʽ������ִ������ʼִ�У������ִ�������ڴ�ͳ��C��ʽ�н���main�ĺ�ʽ������Windows����WinMain��һ��ִ����������ʽ����ͨ����ϵͳ����CreateThread��ָ����ʼִ������ʽ�������������µ�ִ������ִ�С���ҵϵͳ��ִ����֮������Ȩʽ���л�����������ڳ���֮���л�����Ȩ�ķ����dz����ơ�

��OS/2��Presentation Manager�У�ÿ��ִ�������Խ���һ��ѶϢ���У�Ҳ���Բ����������ϣ����ִ���������Ӵ�����ôһ��PMִ�������뽨��ѶϢ���С��������ֻ�ǽ�����������ϴ�������ͼ���������ôִ��������Ҫ����ѶϢ���С���Ϊ��ѶϢ���еij��򲻴���ѶϢ���������ǽ����ᵱסϵͳ��Ψһ��������һ����ѶϢ����ִ�����޷���һ��ѶϢ����ִ�����е��Ӵ�����ѶϢ�����ߺ����κη���ѶϢ�ĺ�ʽ�����������ǿ��Խ�ѶϢ���͸�ѶϢ����ִ��������

������PM��ʽд����ѧ������ν����ǵij�ʽ�ָ�Ϊһ��ѶϢ����ִ�����������н������е��Ӵ����������͸��Ӵ���ѶϢ����һ�����߶����ѶϢ����ִ������������ִ���߳��ı���������PM��ʽд���߻��˽⵽��1/10����򡹣������ϣ���ʽд���߱���֪��һ��ѶϢ����ִ���������κ�ѶϢ����Ӧ�ó���1/10�룬�κλ��Ѹ���ʱ������鶼Ӧ������һ��ִ��������ɡ�������еij�ʽд���߶���ѭ��һ������ô��û��PM��ʽ�Ὣϵͳ��ס����1/10�롣

��ִ�����ܹ�
��

���Ѿ�˵��PM�������ó�ʽд�������������ͼ�λ�����ִ�еij�ʽ��ͷʹ�ö��ִ�����ṩ�˱�Ҫ������������������ҽ�Ϊ���ij�ʽ����һ�ּܹ���������ִ������������ʽ����Ҫ�������Ӵ����������а������е��Ӵ�ѶϢ������ʽ���Ա㴦����Щ�Ӵ�������ѶϢ����������ִ����ֻ����һЩ�������������˺���ִ����ͨѶ�����Dz���ʹ���߽��н�����

���԰����ּܹ�����ɣ���ִ��������ʹ�������루������ѶϢ���������������е�����ִ��������Щ���ӵ�ִ���������ʹ�����޹صĹ�����

���仰˵������ʽ����ִ������һ���ϰ壬����������ִ�������ϰ��ְԱ���ϰ彫��Ĺ�������ְԱ�����������Լ����ֺ�������ϵ����Ϊ��Щִ����������ְԱ����������ִ����������������Լ��ļ����д��ᡣ���ǻ����������Լ��Ĺ����������������ϰ壬���ȴ����ǵ���һ������

һ����ʽ�е�ִ������ͬһ����IJ�ͬ���֣�������ǹ��ó������Դ���������ʹ򿪵ĵ�������Ϊִ�������ó�ʽ�ļ����壬�������ǻ����þ�̬������Ȼ����ÿ��ִ�������������Լ��Ķѵ�����˶�̬������ÿ��ִ������Ψһ�ġ�ÿ��ִ�������и��ԵĴ�����״̬������ѧ����������״̬�������״̬�ڽ���ִ�����л��ڼ䱻����ͻָ���

ִ������ġ�������
��

��ȷ����ơ�д���Ͳ���һ�����ӵĶ�ִ����Ӧ�ó�ʽ��Ȼ��Windows��ʽд���߿��������������ѵĹ���֮һ����Ϊ����Ȩʽ�๤ϵͳ�������κ�ʱ���ж�һ��ִ��������������Ȩ�л�����һ��ִ�����У�������ִ����֮��������޷�Ԥ�ϵ�����������õ������

��ִ������ʽ�е�һ�������Ĵ��󱻳�Ϊ������״̬��race condition�������ⷢ���ڳ�ʽд���߼���һ��ִ��������һ��ִ������Ҫij����֮ǰ�Ѿ������ijЩ��������׼�����ϣ���ʱ��Ϊ�˰���Э��ִ�����Ļ����ҵϵͳҪ�������ʽ��ͬ����һ����ͬ���źţ�semaphore������������ʽд�����ڳ�ʽ���е�ijһ����ֹһ��ִ������ִ�У�ֱ����һ��ִ�������ź���������Ϊֹ�������ͬ���źŵ��ǡ��ٽ�����critical section���������dz�ʽ���в����жϵIJ��֡�

����ͬ���źŻ����ܲ�����Ϊ��������deadlock�����ij���ִ���������ⷢ��������ִ����������ֹ����һ����ִ�У�������ִ�е�Ψһ�취�������Ǽ�����ǰִ�С�

���˵��ǣ�32λԪ��ʽ��16λԪ��ʽ���ֿܵ�ִ�������漰��ijЩ���⡣���磬�ٶ�һ��ִ����ִ������ļ�������

lCount++ ;

����lCount��������ִ����ʹ�õ�һ��32λԪ��long��̬������C�е��������������Ϊ������е��ָ���һ���������ĵ�16λԪ��1�����ڶ���ָ��κο��ܵĽ�λ�ӵ���16λ�ϡ��ٶ���ҵϵͳ����������е��ָ��֮���ж���ִ���������lCount�ڵ�һ����е��ָ��֮ǰ��0x0000FFFF����ôlCount��ִ�������ж�ʱΪ0������������һ��ִ������������ֵ��ֻ�е�ִ��������ִ��ʱ��lCount�Ż����ӵ���ȷ��ֵ0x00010000��

������Щż���ᵼ�²�������Ĵ���֮һ����16λԪ��ʽ�У������������ȷ�ķ����ǽ�����������һ���ٽ������У������ڼ�ִ�������ᱻ�жϡ�Ȼ������һ��32λԪ��ʽ�У�����������ȷ�ģ���Ϊ��������Ϊһ����е��ָ�

Windows�ĺô�
��

32λԪWindows�汾������Windows NT��Windows 98����һ�������л���ѶϢ���С�����ʵ���ƺ��dz��ã����һ����ʽ���ڻ���һ�γ�ʱ�䴦��һ��ѶϢ����ô����λ춸ó�ʽ���Ӵ���ʱ�������α꽫����Ϊһ��ʱ�ӣ����ǵ��������Ƶ���һ����ʽ���Ӵ���ʱ�������α꽫��Ϊ�����ļ�ͷ��״��ֻ�谴һ�¾Ϳ��Խ���һ���Ӵ��ᵽǰ������

Ȼ����ʹ������Ȼ����ʹ�����ڴ��������������Ǹ���ʽ����Ϊ��Щ��������ֹ��ʽ��������ѶϢ���ⲻ��������ϣ���ġ�һ����ʽӦ����������ʱ����ѶϢ�ģ�������ʱ����Ҫʹ�ô���ִ�����ˡ�

��Windows NT��Windows 98�У�û��ѶϢ����ִ��������ѶϢ����ִ����������ÿ��ִ�����ڽ���ʱ���������Լ���ѶϢ���У��Ӷ�������PM��ʽ�й��ִ������һЩ����涨��Ȼ�����ڴ��������£�����Ȼ��ͨ��һ��ר�Ŵ���ѶϢ��ִ�����е�ѶϢ���������룬�����߳���ҵ������Щ�������Ӵ���ִ�������������ֽṹ������������������ģ����ǽ�������һ�㣩��

���и��õ����飺Windows NT��Windows 98���и���ʽ����ִ����ɱ��ͬһ�����е���һ��ִ������������ʼ��д��ִ������ʽ��ʱ�������ᷢ�����ֹ�������ʱ�Ǻܷ���ġ�OS/2�����ڰ汾û�С�ɱ��ִ�������ĺ�ʽ��

����ĺ�ѶϢ�����ٶ�����Ļ����Ǻ�ѶϢ����Windows NT��Windows 98ʵ����һЩ����Ϊ��ִ�������򴢴�ռ䣨TLS��thread local storage�����Ĺ��ܡ�Ϊ���˽���һ�㣬�ع�һ������ǰ���ᵽ���ģ���̬��������һ����ʽ��˵�������������������������ִ����֮���DZ����õģ���Ϊ����λ춳�������ϴ���ռ��С���̬��������һ����ʽ��˵���������������ÿһ��ִ��������Ψһ�ģ���Ϊ����ռ�ݶѵ��ϵĿռ䣬��ÿ��ִ�����������Լ��Ķѵ���

��ʱ����������ִ����ʹ����ͬ�ĺ�ʽ��������Щִ����ʹ��Ψһ�ִ�����ľ�̬�������ǻ�����ܴ�����������ִ�������򴢴�ռ䣬�����漰һЩWindows��ʽ���У�����Microsoft��ΪC������������չ��ʹִ�������򴢴�ռ��ʹ�ø�͸���ڳ�ʽд���ߡ�

�¸������ģ�֧Ԯ��ִ�����ˣ�
��

��Ȼ�Ѿ�������ִ��������״����������չ��һ��ִ������δ������ʱ�����˻����һ��ʹ����ҵϵͳ���ṩ��ÿһ�ֹ������Եij嶯���������ǣ��������ϰ��ߵ�������ǰ��˵��������˵�����¹��ܷdz��ţ����������Լ��ij�ʽ����һЩ�����¹��ܰɡ���Ȼ����������һ�����ڵ�ʱ�䣬��ͼȥ�˽�����Ӧ�ó�ʽ��δ������¹��ܻ��档

Ӧ��ע����ǣ��ڲ�����Ҫ��ִ������Ӧ��ϵͳ�м����ִ������û���κ�����ġ�������ij�ʽ��ʾɳ©�α��ʱ��̫�������������ʹ��PeekMessage����������ɳ©�α�ij��֣���ô�����¹滮���ij�ʽ�ܹ���ʹ�ö�ִ�������ܻ���һ�������⡣�������Σ�������Ϊ�����Լ��������ܻ��ڳ�ʽ���в����µĴ���

��ijЩ����£�ɳ©�α�ij��ֿ�������ȫ�ʵ��ġ�����ǰ���ᵽ����1/10����򡹣�����һ���󵵰������������ܻỨ�Ѷ��1/10���ʱ�䣬���Ƿ���ζ���������볣ʽӦ���ڷ����ִ������ʵ���أ�û�б�Ҫ����ʹ��������һ����ʽ�򿪵���ʱ����������ͨ����������ɸò��������������볣ʽ���ڷ����ִ������ֻ�����Ӷ���ĸ�������ʹ�������������ѿ�ҫ���ڱ�д��ִ������ʽ��Ҳ��ȫ��ֵ����������

WINDOWS�Ķ�ִ��������
��

�����µ�ִ������API��ʽ��CreateThread�������﷨���£�

hThread = CreateThread (&security_attributes, dwStackSize, ThreadProc, 
                        pParam, dwFlags, &idThread) ;

��һ��������ָ��SECURITY_ATTRIBUTES��̬�Ľṹ��ָ�ꡣ��Windows 98�к��Ըò�������Windows NT�У�������ΪNULL���ڶ��������������ִ�����ij�ʼ�ѵ���С��Ԥ��ֵΪ0�����κ�����£�Windows������Ҫ��̬�ӳ��ѵ��Ĵ�С��

CreateThread�ĵ�����������ָ��ִ������ʽ��ָ�ꡣ��ʽ����û�����ƣ����DZ�����������ʽ���棺

DWORD WINAPI ThreadProc (PVOID pParam) ;

CreateThread�ĵ��ĸ�����Ϊ���ݸ�ThreadProc�IJ�����������ִ�����ʹ���ִ�����Ϳ��Թ������ϡ�

CreateThread�ĵ��������ͨ��Ϊ0������������ִ����������ִ��ʱΪ���CREATE_SUSPENDED��ִ��������ֱͣ������ResumeThread���ָ�ִ������ִ��Ϊֹ��������������һ��ָ�ָ꣬�����ִ����IDֵ�ı�����

�����Windows��ʽд����ϲ������PROCESS.H��ͷ�����������Cִ��ʱ�ڳ�ʽ�⺯ʽ_beginthread�������﷨���£�

hThread = _beginthread (ThreadProc, uiStackSize, pParam) ;

�����򵥣���춴����Ӧ�ó�ʽ�����������ִ������ʽ���﷨Ϊ��

void __cdecl ThreadProc (void * pParam) ;

�����������
��

��ʽ20-1 RNDRCTMT�ǵ��������RANDRECT��ʽ�Ķ�ִ�����汾������������RANDRECTʹ�õ���PeekMessage��Ȧ����ʾһϵ�е�������Ρ�

 ï¿½ï¿½Ê½20-1  RNDRCTMT
RNDRCTMT.C
/*---------------------------------------------------------------------------
   	RNDRCTMT.C -- 	Displays Random Rectangles
                 						(c) Charles Petzold, 1998
  -------------------------------------------------------------------------*/

#include <windows.h>
#include <process.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
HWND 	hwnd ;
int 	cxClient, cyClient ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("RndRctMT") ;
     	MSG          	msg ;
     	WNDCLASS     	wndclass ;
     
     	wndclass.style         			= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       			= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     	
     	if (!RegisterClass (&wndclass))
     	{
        MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      	szAppName, MB_ICONERROR) ;
          		return 0 ;
     }
     	hwnd = CreateWindow (	szAppName, TEXT ("Random Rectangles"),
                          	WS_OVERLAPPEDWINDOW,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

VOID Thread (PVOID pvoid)
{
	HBRUSH 	hBrush ;
     	HDC    		hdc ;
     	int    		xLeft, xRight, yTop, yBottom, iRed, iGreen, iBlue ;
     
     	while (TRUE)
     {
          		if (cxClient != 0 || cyClient != 0)
          		{
               			xLeft   		= rand () % cxClient ;
               			xRight  		= rand () % cxClient ;
               			yTop    	= rand () % cyClient ;
               			yBottom 	= rand () % cyClient ;
               			iRed    		= rand () & 255 ;
               			iGreen  		= rand () & 255 ;
               			iBlue   		= rand () & 255 ;
               
               		hdc = GetDC (hwnd) ;
               		hBrush = CreateSolidBrush (RGB (iRed, iGreen, iBlue)) ;
               		SelectObject (hdc, hBrush) ;
               
               	Rectangle (hdc,	min (xLeft, xRight), min (yTop, yBottom),
                max (xLeft, xRight), max (yTop, yBottom)) ;
               
               				ReleaseDC (hwnd, hdc) ;
               				DeleteObject (hBrush) ;
          			}
     	}
}
LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	switch (message)
     	{
     	case WM_CREATE:
          			_beginthread (Thread, 0, NULL) ;
          			return 0 ;
          
     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

�ڽ�����ִ������Windows��ʽʱ����Ҫ�ڡ�Project Settings���Ի���������һЩ�޸ġ�ѡ��C/C++��ҳ���ǩ��Ȼ���ڡ�Category������ʽ�嵥������ѡ��Code Generation�����ڡ�Use Run-Time Library������ʽ�嵥�����У����Կ�����춡�Release���趨�ġ�Single-Threaded�������Debug�趨�ġ�Debug Single-Threaded��������Щ�ֱ��Ϊ��Multithreaded���͡�Debug Multithreaded�����⽫�ѱ���������Ϊ/MT�����DZ������ڱ����ִ������Ӧ�ó�ʽ����Ҫ�ġ������˵������������.OBJ�����в���LIBCMT.LIB��������������LIBC.LIB�������ʽʹ�����������ִ���ڳ�ʽ�⺯ʽ���ᡣ

LIBC.LIB��LIBCMT.LIB��������C���Գ�ʽ�⺯ʽ����ЩC���Գ�ʽ�⺯ʽ������̬���ϡ����磬���strtok��ʽ���ܱ������ض�κ��У��������ھ�̬�������д�����һ��ָ�ꡣ�ڶ�ִ������ʽ�У�ÿ��ִ����������strtok��ʽ�������Լ��ľ�ָ̬�ꡣ��ˣ������ʽ�Ķ�ִ�����汾��΢��ͬ춵�ִ������strtok��ʽ��

ͬʱ��ע�⣬����RNDRCTMT.C�а����˱�ͷ����PROCESS.H�������������һ����Ϊ_beginthread�ĺ�ʽ��������һ���µ�ִ������ֻ�ж�����_MTʶ���֣��Ż����������ʽ������/MT������һ�������

��RNDRCTMT.C��WinMain��ʽ�У���CreateWindow���ص�hwndֵ��������һ����������У����cxClient��cyClientֵҲ�������Ӵ�ѶϢ������ʽ��WM_SIZEѶϢ��á�

�Ӵ�ѶϢ������ʽ�������׵ķ�������_beginthread���򵥵���ִ������ʽ��λַ����ΪThread����Ϊ��һ����������������ʹ��0��ִ������ʽ����VOID����һ���������ò�����һ��ָ��VOID��ָ�ꡣ��RNDRCTMT�е�Thread��ʽ��ʹ�����������

�ں�����_beginthread��ʽ֮�ᣬִ������ʽ���Լ���ִ������ʽ���ܺ��е������κκ�ʽ���еij�ʽ��ͳ�ʽ�е�������ʽ��ͬʱִ�С��������߶��ִ����ʹ��һ�������е�ͬһ��ʽ������������£���̬��������������ڶѵ��ϣ���ÿ��ִ������Ψһ�ġ��Գ����е�����ִ������˵�����еľ�̬��������һ���ġ�������Ӵ�ѶϢ������ʽ�趨�����cxClient��cyClient��������Thread��ʽʹ�õķ�ʽ��

��ʱ����ҪΨһ춸���ִ�����ij������������ϡ�ͨ�������������Ǿ�̬����������Windows 98�У�������ʹ�á�ִ�������򴢴�ռ䡹���ҽ��ڱ�������������ۡ�

��ʽ��ƾ���������
��

1986��10��3�գ�Microsoft������Ϊ��һ�죬��Ե�����־������ļ����༭�����ߵļ�̵ļ����д��ᣬ���������ǵ�ʱ��һ�����Բ�Ʒ���������ǵĵ�һ����̸ʽ����������QuickBASIC 2.0����ʱ��Windows 1.0���ֻ�����һ�꣬����û����֪������ʲôʱ���ܵõ���û������ƵĶ������⻨�˺ü��꣩����һ�¼����ڲ�ͬ�IJ���ԭ�������Microsoft�Ĺ�����Ա���ٰ�ġ�Storm the Gates����ʽ��ƾ�����Bill Gatesʹ��QuickBASIC 2.0�������Գ��������Ա����ʹ������ѡ����κ����Բ�Ʒ��

�����������Ǵӹ����������Ŀ����ѡ�����ģ���ѡ��Щ��Ҫд��Լ��Сʱ��ʽ����������⣩���������£�

����һ�������ĸ��Ӵ��Ķ๤ģ���ʽ����һ���Ӵ�������ʾһϵ�еĵ��������ڶ���������ʾһϵ�еĵ�����������������������ʾFibonacci���У�Fibonacci����������0��1��ʼ����ͷÿһ����������ǰ�������ĺͣ���0��1��1��2��3��5��8�ȵȣ����������Ӵ�Ӧ�������ִﵽ�Ӵ��ײ�ʱ���߽��й�����������������Ӵ����ݡ����ĸ��Ӵ�������ʾ����뾶��Բ������ʽ�����ڰ���һ��Escape��ʱ��ֹ��

��Ȼ����1986��10�£���DOS��ִ�е�����һ����ʽ���ֻ����ģ��๤���ѣ�����û��һ�������߾����㹻���������������д����Ҳû���㹻��֪ʶ����ΪWindows��д�����ʽ�����ߣ������Ҫ��ô������Ȼ����ֻ����Сʱ�ˣ�

�μ���ξ����Ĵ�����˱�д��һ����ʽ����өĻ��Ϊ�ĸ����򣬳�ʽ�а���һ����Ȧ�����θ���ÿ���Ӵ���Ȼ�����Ƿ�����Escape������ͬDOS�����µĴ�ͳϰ�ߣ���ʽռ���˰ٷ�֮�ٵ�CPU����ʱ�䡣

�����Windows 1.0��д��ʽ����ô����������Ƴ�ʽ20-2 MULTI1�Ľ������˵�����ơ�������Ϊ�ұ�д�ij�ʽ��32λԪ�ģ�����ʽ�ṹ���൱��ij�ʽ�룭���˱����ͺ�ʽ���������Լ�Unicode֧Ԯ��������ͬ�ġ�

 ï¿½ï¿½Ê½20-2  MULTI1
MULTI1.C
/*--------------------------------------------------------------------------
   	MULTI1.C -- 	Multitasking Demo
               						(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#include <windows.h>
#include <math.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int cyChar ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("Multi1") ;
     	HWND         				hwnd ;
     	MSG          				msg ;
     	WNDCLASS     			wndclass ;
     
     	wndclass.style         		= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   		= WndProc ;
     	wndclass.cbClsExtra    		= 0 ;
     	wndclass.cbWndExtra    		= 0 ;
     	wndclass.hInstance     		= hInstance ;
     	wndclass.hIcon         		= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       		= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  	= NULL ;
     	wndclass.lpszClassName 	= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
        MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                    szAppName, MB_ICONERROR) ;
          		return 0 ;
     }
     hwnd = CreateWindow (	szAppName, TEXT ("Multitasking Demo"),
                          	WS_OVERLAPPEDWINDOW,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
	return msg.wParam ;
}

int CheckBottom (HWND hwnd, int cyClient, int iLine)
{
     	if (iLine * cyChar + cyChar > cyClient)
     	{
          		InvalidateRect (hwnd, NULL, TRUE) ;
          		UpdateWindow (hwnd) ;
          		iLine = 0 ;
     }
     	return iLine ;
}

// -------------------------------------------------------------------------
// Window 1: Display increasing sequence of numbers
// -------------------------------------------------------------------------

LRESULT APIENTRY WndProc1 (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static int	 	iNum, iLine, cyClient ;
     	HDC     				hdc ;
     	TCHAR      				szBuffer[16] ;
     
     	switch (message)
     	{
     	case 	WM_SIZE:
          			cyClient = HIWORD (lParam) ;
          			return 0 ;

     	case 	WM_TIMER:
          			if (iNum < 0)
               					iNum = 0 ;

          			iLine = CheckBottom (hwnd, cyClient, iLine) ;
          			hdc = GetDC (hwnd) ;

          			TextOut (hdc, 0, iLine * cyChar, szBuffer, 
                  						wsprintf (szBuffer, TEXT ("%d"), iNum++)) ;

          			ReleaseDC (hwnd, hdc) ;
          			iLine++ ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

// --------------------------------------------------------------------------
// Window 2: Display increasing sequence of prime numbers
// --------------------------------------------------------------------------

LRESULT APIENTRY WndProc2 (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static int 		iNum = 1, iLine, cyClient ;
     	HDC        				hdc ;
     	int        				i, iSqrt ;
     	TCHAR      				szBuffer[16] ;
     
     	switch (message)
     	{
     	case 	WM_SIZE:
          			cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_TIMER:
          			do   		{
               					if (++iNum < 0)
                    							iNum = 0 ;
               
               					iSqrt = (int) sqrt (iNum) ;

               					for (i = 2 ; i <= iSqrt ; i++)
                    							if (iNum % i == 0)
                         									break ;
          			}
          			while (i <= iSqrt) ;
          
          			iLine = CheckBottom (hwnd, cyClient, iLine) ;
          			hdc = GetDC (hwnd) ;

          			TextOut (	hdc, 0, iLine * cyChar, szBuffer, 
                   							wsprintf (szBuffer, TEXT ("%d"), iNum)) ;
          			ReleaseDC (hwnd, hdc) ;
          			iLine++ ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

// --------------------------------------------------------------------------
// Window 3: Display increasing sequence of Fibonacci numbers
// --------------------------------------------------------------------------

LRESULT APIENTRY WndProc3 (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	static int 		iNum = 0, iNext = 1, iLine, cyClient ;
     	HDC       	 			hdc ;
     	int        				iTemp ;
     	TCHAR      				szBuffer[16] ;
     
     	switch (message)
     	{
     	case WM_SIZE:
          			cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_TIMER:
          			if (iNum < 0)
          			{
               				iNum  = 0 ;
               				iNext = 1 ;
          			}
          
          			iLine = CheckBottom (hwnd, cyClient, iLine) ;
          			hdc = GetDC (hwnd) ;

          			TextOut (	hdc, 0, iLine * cyChar, szBuffer, 
                   							wsprintf (szBuffer, "%d", iNum)) ;
          			ReleaseDC (hwnd, hdc) ;
          			iTemp		= 	iNum ;
          			iNum 		= 	iNext ;
          			iNex		+= 	iTemp ;
          			iLine++ ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

// --------------------------------------------------------------------------
// Window 4: Display circles of random radii
// ---------------------------------------------------------------------------

LRESULT APIENTRY WndProc4 (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static int 		cxClient, cyClient ;
     	HDC        				hdc ;
     	int        				iDiameter ;
     
     	switch (message)
     	{
     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_TIMER:
          			InvalidateRect (hwnd, NULL, TRUE) ;
          			UpdateWindow (hwnd) ;
          
          			iDiameter = rand() % (max (1, min (cxClient, cyClient))) ;
          			hdc = GetDC (hwnd) ;
          
          			Ellipse (hdc, 		(cxClient - iDiameter) / 2,
                        			(cyClient - iDiameter) / 2,
                        			(cxClient + iDiameter) / 2,
                        			(cyClient + iDiameter) / 2) ;
          
          			ReleaseDC (hwnd, hdc) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
// --------------------------------------------------------------------------
// Main window to create child windows
// --------------------------------------------------------------------------

LRESULT APIENTRY WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static HWND    		hwndChild[4] ;
     	static TCHAR * 	szChildClass[] =	{ TEXT ("Child1"), TEXT ("Child2"),
        TEXT ("Child3"), TEXT ("Child4") } ;
     	static WNDPROC 		ChildProc[] = 	{ WndProc1, WndProc2, WndProc3, WndProc4 } ;
     	HINSTANCE      			hInstance ;
     	int            					i, cxClient, cyClient ;
     	WNDCLASS       				wndclass ;
     
     	switch (message)
     	{
     	case 	WM_CREATE:
          			hInstance = (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE) ;
          
          			wndclass.style         				= CS_HREDRAW | CS_VREDRAW ;
          			wndclass.cbClsExtra    		= 0 ;
          			wndclass.cbWndExtra    		= 0 ;
          			wndclass.hInstance     		= hInstance ;
          			wndclass.hIcon         		= NULL ;
          			wndclass.hCursor       		= LoadCursor (NULL, IDC_ARROW) ;
          			wndclass.hbrBackground 	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
          			wndclass.lpszMenuName  	= NULL ;
          
          			for (i = 0 ; i < 4 ; i++)
          			{
               					wndclass.lpfnWndProc   = ChildProc[i] ;
               					wndclass.lpszClassName = szChildClass[i] ;
               
               					RegisterClass (&wndclass) ;
               
               					hwndChild[i] = CreateWindow (szChildClass[i], NULL,
                                WS_CHILDWINDOW | WS_BORDER | WS_VISIBLE,
                                0, 0, 0, 0, 
                                hwnd, (HMENU) i, hInstance, NULL) ;
          			}

          			cyChar = HIWORD (GetDialogBaseUnits ()) ;
          			SetTimer (hwnd, 1, 10, NULL) ;
          			return 0 ;
          
     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          
          			for (i = 0 ; i < 4 ; i++)
               	MoveWindow (hwndChild[i], 	(i % 2) * cxClient / 2,
                                            (i > 1) * cyClient / 2,
                          cxClient / 2, cyClient / 2, TRUE) ;
          				return 0 ;
          
     	case 	WM_TIMER:
          			for (i = 0 ; i < 4 ; i++)
               				SendMessage (hwndChild[i], WM_TIMER, wParam, lParam) ;
          
          			return 0 ;
          
     	case 	WM_CHAR:
          			if (wParam == '\x1B')
               					DestroyWindow (hwnd) ;
          
          			return 0 ;
          
     	case 	WM_DESTROY:
          			KillTimer (hwnd, 1) ;
          			PostQuitMessage (0) ;
          			return 0 ;
 	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

�������ʽ��ʵ����û��ʲô����û�����Ķ��������Ӵ������ĸ����Ӵ���ÿ�����Ӵ�ռ����ʾ�����һ�����ޡ����Ӵ����趨һ��Windows��ʱ��������WM_TIMERѶϢ���ĸ����Ӵ��е�ÿһ����

ͨ��һ��Windows��ʽӦ�ñ����㹻����Ѷ�Ա���WM_PAINTѶϢ�����ڼ��ؽ����Ӵ��е����ݡ�MULTI1û����ô������Ȼ�����ƺ�����Ӵ����ٶ����֮�죬��������Ϊ���Dz���Ҫ�ġ�

WndProc2�е�������������Ч�ʲ����ܸߣ�������Ч�����һ��������1������������û�б����������ô�����������������Ȼ��Ҫ���һ�����Ƿ�����������Ҫ��ʹ��С춱������������������������������������ֻ��ʹ������С춱��������ƽ����������ƽ���������Ƿ�����������ԭ�򣬷��򣬸ó�ʽ������ȫ���������ij�ʽ��

MULTI1��ʽû��ʲô���õĵط���ʹ��Windows��ʱ������Windows�����ڣ���Ŀǰ���汾��ģ��๤��һ�ֺ÷�����Ȼ������ʱ����ʹ����ʱ�����˳�ʽ���ٶȡ������ʽ������WM_TIMERѶϢ�����и������������Ӵ�������ʱ��ʣ�������Ļ����Ǿ���ζ������û�г���������ǵĻ�����Դ��

һ�ֿ��ܵĽ���������ڵ���WM_TIMERѶϢ�����ڼ�������λ��߸���εĸ��£����ǵ��׶��ٴ��أ��ⲻ�ò�����춻������ٶȣ����кܴ�ı䶯�ԡ�����Ȼ�������дһ��ֻ�������25MHz��386��50MHz��486��100-GHz��Pentium VII�ϵij�ʽ�ɡ�

��ִ�����������
��

����������һ����������ʽ��������һ�ֶ�ִ����������������ʽ20-3 MULTI2��ʾ��

 ï¿½ï¿½Ê½20-3  MULTI2
MULTI2.C
/*---------------------------------------------------------------------------
   	MULTI2.C -- 	Multitasking Demo
               						(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#include <windows.h>
#include <math.h>
#include <process.h>

typedef struct
{
     	HWND 		hwnd ;
     	int  		cxClient ;
     	int  		cyClient ;
     	int  		cyChar ;
     	BOOL bKill ;
}
PARAMS, *PPARAMS ;
LRESULT APIENTRY WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("Multi2") ;
     	HWND         				hwnd ;
     	MSG          				msg ;
     	WNDCLASS     			wndclass ;
     
     	wndclass.style         			= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       			= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
        MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                    szAppName, MB_ICONERROR) ;
          		return 0 ;
     	}
     
     	hwnd = CreateWindow (	szAppName, TEXT ("Multitasking Demo"),
                          	WS_OVERLAPPEDWINDOW,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

int CheckBottom (HWND hwnd, int cyClient, int cyChar, int iLine)
{
     	if (iLine * cyChar + cyChar > cyClient)
     	{
          		InvalidateRect (hwnd, NULL, TRUE) ;
          		UpdateWindow (hwnd) ;
          		iLine = 0 ;
     	}
     	return iLine ;
}

// --------------------------------------------------------------------------
// Window 1: Display increasing sequence of numbers
// --------------------------------------------------------------------------

void Thread1 (PVOID pvoid)
{
     	HDC     			hdc ;
     	int     			iNum = 0, iLine = 0 ;
     	PPARAMS 		pparams ;
     	TCHAR   			szBuffer[16] ;
     
     	pparams 	= (PPARAMS) pvoid ;
     
     	while (!pparams->bKill)
     	{
          		if (iNum < 0)
               				iNum = 0 ;
          		iLine = CheckBottom (	pparams->hwnd,		pparams->cyClient,
    pparams->cyChar,	iLine) ;

          		hdc = GetDC (pparams->hwnd) ;
          
          		TextOut (	hdc, 0, iLine * pparams->cyChar, szBuffer, 
                   						wsprintf (szBuffer, TEXT ("%d"), iNum++)) ;               
          
          		ReleaseDC (pparams->hwnd, hdc) ;
          		iLine++ ;
     	}
	_endthread () ;
}

LRESULT APIENTRY WndProc1 (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static PARAMS params ;
     	switch (message)
     	{
     	case 	WM_CREATE:
          			params.hwnd = hwnd ;
          			params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
          			_beginthread (Thread1, 0, ¶ms) ;
          			return 0 ;
          
     	case 	WM_SIZE:
          			params.cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			params.bKill = TRUE ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

// --------------------------------------------------------------------------
// Window 2: Display increasing sequence of prime numbers
// --------------------------------------------------------------------------

void Thread2 (PVOID pvoid)
{
	HDC     			hdc ;
     	int     			iNum = 1, iLine = 0, i, iSqrt ;
     	PPARAMS 		pparams ;
     	TCHAR   			szBuffer[16] ;
     
     	pparams = (PPARAMS) pvoid ;
     	while (!pparams->bKill)
     	{
          		do
          		{
               			if (++iNum < 0)
                    					iNum = 0 ;
               			iSqrt = (int) sqrt (iNum) ;
               			for (i = 2 ; i <= iSqrt ; i++)
                    					if (iNum % i == 0)
                         							break ;
          		}
          		while (i <= iSqrt) ;
          		iLine = CheckBottom 	(	pparams->hwnd,		pparams->cyClient,
    pparams->cyChar,	iLine) ;
          
          		hdc = GetDC (pparams->hwnd) ;
          
          		TextOut (	hdc, 0, iLine * pparams->cyChar, szBuffer, 
                   						wsprintf (szBuffer, TEXT ("%d"), iNum)) ;
          
          		ReleaseDC (pparams->hwnd, hdc) ;
          		iLine++ ;
     	}
	_endthread () ;
}

LRESULT APIENTRY WndProc2 (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static PARAMS params ;
     	switch (message)
     	{
     	case 	WM_CREATE:
          			params.hwnd = hwnd ;
          			params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
          			_beginthread (Thread2, 0, ¶ms) ;
          			return 0 ;
          
     	case 	WM_SIZE:
          			params.cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			params.bKill = TRUE ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

// Window 3: Display increasing sequence of Fibonacci numbers
// ----------------------------------------------------------

void Thread3 (PVOID pvoid)
{
     	HDC     			hdc ;
     	int    			iNum = 0, iNext = 1, iLine = 0, iTemp ;
     	PPARAMS 		pparams ;
     	TCHAR   			szBuffer[16] ;
     
     	pparams = (PPARAMS) pvoid ;
     	while (!pparams->bKill)
     {
          			if (iNum < 0)
          			{
               				iNum  = 0 ;
               				iNext = 1 ;
          		}
          		iLine = CheckBottom (	pparams->hwnd,   	pparams->cyClient,
    pparams->cyChar, iLine) ;

          		hdc = GetDC (pparams->hwnd) ;
          
          		TextOut (hdc, 0, iLine * pparams->cyChar, szBuffer, 
                   						wsprintf (szBuffer, TEXT ("%d"), iNum)) ;
          
          		ReleaseDC (pparams->hwnd, hdc) ;
          		iTemp  = iNum ;
          		iNum   = iNext ;
          		iNext += iTemp ;
          		iLine++ ;
     	}
     	_endthread () ;
}

LRESULT APIENTRY WndProc3 (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static PARAMS params ;
     	switch (message)
     	{
     	case 	WM_CREATE:
          			params.hwnd = hwnd ;
          			params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
          			_beginthread (Thread3, 0, ¶ms) ;
          			return 0 ;

     	case 	WM_SIZE:
          			params.cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			params.bKill = TRUE ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

// -------------------------------------------------------------------------
// Window 4: Display circles of random radii
// -------------------------------------------------------------------------

void Thread4 (PVOID pvoid)
{
     	HDC     			hdc ;
     	int     			iDiameter ;
     	PPARAMS 		pparams ;
     
     	pparams = (PPARAMS) pvoid ;
     	while (!pparams->bKill)
     	{
          		InvalidateRect (pparams->hwnd, NULL, TRUE) ;
          		UpdateWindow (pparams->hwnd) ;
          
          		iDiameter = 	rand() % (max (1,
                min (pparams->cxClient, pparams->cyClient))) ;
          
          		hdc = GetDC (pparams->hwnd) ;
          
          		Ellipse (hdc, 	(pparams->cxClient - iDiameter) / 2,
                        		(pparams->cyClient - iDiameter) / 2,
                        		(pparams->cxClient + iDiameter) / 2,
                        	    (pparams->cyClient + iDiameter) / 2) ;
          
          		ReleaseDC (pparams->hwnd, hdc) ;
     	}
	_endthread () ;
}

LRESULT APIENTRY WndProc4 	(HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam)
{
     	static PARAMS params ;
     	switch (message)
     	{
     	case 	WM_CREATE:
          			params.hwnd = hwnd ;
          			params.cyChar = HIWORD (GetDialogBaseUnits ()) ;
          			_beginthread (Thread4, 0, ¶ms) ;
          			return 0 ;
          
     	case 	WM_SIZE:
          			params.cxClient = LOWORD (lParam) ;
          			params.cyClient = HIWORD (lParam) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			params.bKill = TRUE ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

// --------------------------------------------------------------------------
// Main window to create child windows
// --------------------------------------------------------------------------

LRESULT APIENTRY WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static HWND    		hwndChild[4] ;
     	static TCHAR * szChildClass[] = { TEXT ("Child1"), TEXT ("Child2"),
        TEXT ("Child3"), TEXT ("Child4") } ;
     	static WNDPROC 	ChildProc[] = { WndProc1, WndProc2, WndProc3, WndProc4 } ;
     	HINSTANCE      		hInstance ;
     	int            				i, cxClient, cyClient ;
     	WNDCLASS       			wndclass ;
     
     	switch (message)
     	{
     	case 	WM_CREATE:
          			hInstance = (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE) ;
          			wndclass.style         					= CS_HREDRAW | CS_VREDRAW ;
          			wndclass.cbClsExtra    			= 0 ;
        			wndclass.cbWndExtra    			= 0 ;
          			wndclass.hInstance     			= hInstance ;
          			wndclass.hIcon         			= NULL ;
          			wndclass.hCursor       			= LoadCursor (NULL, IDC_ARROW) ;
          			wndclass.hbrBackground 		= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
          			wndclass.lpszMenuName  = NULL ;
          
          			for (i = 0 ; i < 4 ; i++)
          			{
               				wndclass.lpfnWndProc		= ChildProc[i] ;
               				wndclass.lpszClassName 	= szChildClass[i] ;
               
               				RegisterClass (&wndclass) ;
               
               				hwndChild[i] = 	CreateWindow (szChildClass[i], NULL,
                            WS_CHILDWINDOW | WS_BORDER | WS_VISIBLE,
                            0, 0, 0, 0, 
                            hwnd, (HMENU) i, hInstance, NULL) ;
          			}
          
          			return 0 ;
          
     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          
          			for (i = 0 ; i < 4 ; i++)
               					MoveWindow (hwndChild[i], (i % 2) * cxClient / 2,
                                         				 (i > 1) * cyClient / 2,
                           		            cxClient / 2, cyClient / 2, TRUE) ;
          			return 0 ;
          
     	case 	WM_CHAR:
          			if (wParam == '\x1B')
               					DestroyWindow (hwnd) ;
          
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

MULTI2.C��WinMain��WndProc��ʽ�dz������MULTI1.C�е�ͬ����ʽ��WndProcΪ�ĸ��Ӵ�ע���������Ӵ���𣬽�������Щ�Ӵ�������WM_SIZEѶϢ�����ڼ�������Щ�Ӵ���WndProc��Ψһ��ͬ���������趨Windows��ʱ����Ҳ���ٴ���WM_TIMERѶϢ��

MULTI2�нϴ�ĸı���ÿ�����Ӵ�ѶϢ������ʽ͸����WM_CREATEѶϢ�����ڼ����_beginthread��ʽ��������һ��ִ������������˵��MULTI2��ʽ�����ͬʱִ�е�ִ��������ִ�����������Ӵ�ѶϢ������ʽ���ĸ����Ӵ�ѶϢ������ʽ��������ĸ�ִ����ʹ����ΪThread1��Thread2�ȵĺ�ʽ�����ĸ�ִ������������ĸ��Ӵ���

����RNDRCTMT��ʽ�и����Ķ�ִ������ʽ��û��ʹ��_beginthread�ĵ����������������������һ��������һ��ִ������ִ������32λԪ�����н���Ѷ���ݸ�����ִ������ͨ�������������һ��ָ�꣬������ָ��һ���ṹ��ָ�꣬������ԭ����ִ��������ִ����������Ѷ�������ؽ������������������Կ�������MULTI2��û�����������

��MULTI2��ʽ�����ڳ�ʽ��ͷ������һ����ΪPARAMS�Ľṹ��һ����ΪPPARAMS��ָ��ṹ��ָ�꣬����ṹ�������λ���Ӵ����š��Ӵ��Ŀ��Ⱥ͸߶ȡ���Ԫ�ĸ߶Ⱥ���ΪbKill�IJ��ֱ���������Ľṹ��λ��������ִ������֪������ִ������ʱ��ֹ��

����������һ��WndProc1��������ʾ���������е����Ӵ�ѶϢ������ʽ���Ӵ�ѶϢ������ʽ��÷dz��򵥣�Ψһ�����������һ��PARAMS�ṹ����WM_CREATEѶϢ�����ڼ䣬���趨����ṹ��hwnd��cyChar��λ������_beginthread������һ��ʹ��Thread1��ʽ����ִ�����������ݸ���ִ����һ��ָ��ýṹ��ָ�ꡣ��WM_SIZEѶϢ�����ڼ䣬WndProc1�趨�ṹ��cyClient��λ������WM_DESTROYѶϢ�����ڼ䣬����bKill��λ�趨ΪTRUE��Thread1��ʽͨ����_endthread�ĺ��ж���������Ⲣ���Ǿ��Ա�Ҫ�ģ���Ϊִ���������˳�ִ������ʽ֮�ᱻ�����������Ҫ�˳�һ�������븴�ӵĴ��������ִ����ʱ��_endthread�Ǻ����õġ�

Thread1��ʽ������Ӵ��ϵ�ʵ�ʻ�ͼ�����Һͳ�ʽ�������ĸ�ִ����ͬʱִ�С���ʽ����ָ��PARAMS�ṹ��һ��ָ�꣬������һ��while��Ȧ�����ϼ��bKill��TRUE����FALSE�������FALSE����ô��ʽ�������MULTI1.C�е�WM_TIMERѶϢ�����ڼ�������ͬ����������ʽ�����֡�ȡ��װ�����ݴ��Ų�ʹ��TextOut��ʾ���֡�

������Windows 98��ִ��MULTI2ʱ�����ῴ�����Ӵ�����Ҫ����MULTI1�п�ö࣬���ʾ��ʽ�ڸ�����Ч�����ô���������Դ����MULTI1��MULTI2֮�仹����һ������ͨ���������ƶ���������һ���Ӵ�ʱ���ڶ��Ӵ�ѶϢ������ʽ����һ��ģ̬��Ȧ�����Ӵ��������������ֹͣ����MULTI2�У������������

��������
��

�ƺ�MULTI2��ʽ��û�дﵽ��Ӧ���е��ȹ��ԡ���Ϊʲô��������Ϊ�أ�����������һ��MULTI2.C�е�һЩ��ִ������ȱ�ݡ�����WndProc1��Thread1Ϊ����

WndProc1��MULTI2����ִ������ִ�У���Thread1����ͬʱִ�У�Windows 98��������ִ����֮������л��Dz���Ԥ��ġ��ٶ�Thread1����ִ�У����Ҹպ�ִ���˼��PARAMS�ṹ��bKill��λ�Ƿ�ΪTRUE�ij�ʽ�롣���ֲ�ΪTRUE��������֮��Windows 98������Ȩ�л�����ִ��������ʱʹ������ֹ�˳�ʽ��WndProc1�յ�һ��WM_DESTROYѶϢ����bKill������ΪTRUE��Ŷ��������趨��̫���ˣ���ҵϵͳͻȻ�л���Thread1�У����ú�ʽ����ͼȡ��һ�������ڵ��Ӵ���װ�����ݴ��š�

��ʵ֤�����ⲻ��һ�����⡣Windows 98���ȹ̣�������һ��ִ�������е�ͼ�δ�����ʽֻ��ʧ�ܶ��ѣ������������κ����⡣

��ȷ�Ķ�ִ������ʽд�������漰ִ����ͬ����ʹ�ã��������ٽ������ʹ�ã����ҽ����ϼ�����ϸ�����ۡ������ϣ��ٽ�����ͨ����EnterCriticalSection��LeaveCriticalSection�ĺ��ж����Խ綨�����һ��ִ��������һ���ٽ�������ô��һ��ִ�������޷��ٽ�������ٽ�������һ��ִ�������赵�ڶ�EnterCriticalSection�ĺ����ϣ�ֱ����һ��ִ��������LeaveCriticalSectionʱΪֹ��

��MULTI2�е���һ�����ܴ��ڵ������ǣ�������һ��ִ������ʾ�����ʱ����ִ�������ܻ��յ�һ��WM_ERASEBKGND��WM_PAINTѶϢ�����ʹ���ٽ���������춱��⵱����������ͼ��ͬһ���Ӵ��ϻ�ͼʱ���ܵ��µ��κ����⡣���ǣ�������ʾ��Windows 98��ǡ�������л��˶�ͼ�λ��ƺ�ʽ�Ĵ�ȡ���༴������һ��ִ�������ڻ�ͼ��ʱ��һ��ִ����������ͬһ���Ӵ��ϻ�ͼ��

Windows 98�ļ�����˵����һ��δ����ͼ�κ�ʽ���л������Σ������GDI������续�ʡ���ˢ�����塢����ͼ������͵�ɫ�̵ȣ���ʹ�á��п��ܷ���һ��ִ���������һ�����������һ��ִ������Ȼ��ʹ���������������������ķ���Ҫ��ʹ���ٽ����򣬻�����ò�Ҫ��ִ����֮�乲��GDI�����

Sleep�ĺô�
��

�������ᵽ������Ϊ��һ����ִ������ʽ��˵����õļܹ�����ִ����������ʽ�е������Ӵ����Լ����е��Ӵ�ѶϢ������ʽ�����������е��Ӵ�ѶϢ������ִ������ɱ������������߳���ҵ��

������������������һ��ִ��������������ͨ����Windows�еĶ�����ʹ��WM_TIMERѶϢ��ʵ���ġ�������ִ����û�н����Ӵ�����ô��Ҳ�����յ���ЩѶϢ�����û�м�ʱ���������ֿ��ܻ�ִ�е�̫�졣

���������Sleep��ʽ��ʵ���ϣ�ִ��������Sleep��ʽ���Զ���ִͣ�У��ú�ʽΨһһ���������Ժ���Ƶ�ʱ�䡣Sleep��ʽ������ָ����ʱ���ȥ��ǰ���ᴫ�ؿ���Ȩ�������ʱ���ڣ�ִ��������ͣ�����Ҳ��ᱻ���ø�ʱ��Ƭ�Σ����ܸ�ִ������Ȼ��ȻҪ����tickʱ����һС�εĴ���ʱ�䣬��Ϊϵͳ����ȷ��ִ�����Ƿ�Ӧ�����¿�ʼִ�У�����Sleepһ��ֵΪ0�IJ���������ִ������������δʹ�����ʱ��Ƭ�Ρ�

��һ��ִ��������Sleepʱ��ֻ�Ǹ�ִ��������ָͣ����ʱ�䡣ϵͳ��Ȼִ��������ִ��������Щִ��������ͣ��ִ������������ͬһ�������У�Ҳ����������һ�������С����ڵ�ʮ�����е�SCRAMBLE��ʽ��ʹ����Sleep��ʽ���Է�����������IJ�����

ͨ��������Ӧ����������ִ������ʹ��Sleep��ʽ����Ϊ��������ѶϢ�Ĵ����ٶȣ�������ΪSCRAMBLEû�н����κ��Ӵ������������ʹ��SleepӦ��û�����⡣

ִ����ͬ��
��

��Լÿ��һ�Σ����ҹ�Ԣ����Ľ�ͨ��æ�ضεĺ��̵ƻ�ֹͣ�������������ɽ�ͨ�Ļ��ң���Ȼ�γ�һ���ܱ���ײ�ϱ�Ľγ���������Щ����������һ��

�������������·�ཻ��ʮ��·��Ϊ���ٽ����򡹡�һ�����ϵij���һ�������ij�������ͬʱͨ��һ��ʮ��·�ڶ���ײ���Է�������춽�ͨ���������Բ��ò�ͬ�ķ��������������⡣�����Ұ�������ϡ�ٵ�·�ڣ���������˾���д���������������������ܻ�Ҫ��һ��ͣ����־�������ӷ�æ�Ľ�ͨ��Ҫ���к��̵ƣ����̵������Э��·�ڵĽ�ͨ����Ȼ����Щ�ƺű���������������

�ٽ�����
��

�ڵ�����ҵϵͳ�У���ͳ�ĵ��Գ�ʽ����Ҫ���̵�������Э������֮�����Ϊ��������ִ��ʱ�ƺ���ռ������·������Ҳȷʵ��������û��ʲô��������ǵĹ�����

��ʹ�ڶ๤��ҵϵͳ�У�������ij�ʽҲ�ƺ����Զ�������ִ�У����ǿ��ܻᷢ��һЩ���⡣���磬������ʽ���ܻ���Ҫͬʱ��ͬһ�������ж����߶�ͬһ��������д������������£���ҵϵͳ�ṩ��һ�ֹ��õ����ͼ�¼�����ļ������������������⡣

Ȼ������֧Ԯ��ִ��������ҵϵͳ�У�������û��Ҷ��Ҵ���DZ�ڵ�Σ�ա���������ִ��������ijЩ���ϵ�����������������磬һ��ִ�������Ը���һ�����߶������������һ��ִ��������ʹ����Щ��������ʱ�������һ�����⣬��ʱ�ֲ��ᣨ��ס��ҵϵͳ������Ȩ��һ��ִ�����л�����һ��ִ�����IJ�����ֻ���ڻ�����ָ��֮�䷢�������ֻ��һ��������ִ�������ã���ô����������ĸı�ͨ�������ڵ���ָ���У����DZ�ڵ����ⱻ��С���ˣ���

Ȼ��������ִ�������ü��������������Ͻṹ��ͨ������ô����������߽ṹ����λ������֮�������һ�µġ���ҵϵͳ�����ڸ�����Щ�����ij����м��ж�һ��ִ��������ôʹ����Щ������ִ�����õ��Ľ��Dz�һ�µ����ϡ�

����dz�ͻ�����ˣ�����ͨ���������������Ĵ��󽫶Գ�ʽ����������ƻ�����������Ҫ��������춺��̵Ƶij�ʽд���������԰������Ƕ�ִ������ͨ����Э����ͬ����������ٽ����򡣴����ϣ�һ���ٽ��������һ�鲻���жϵij�ʽ�롣

���ĸ���ʽ����ٽ�����Ҫʹ����Щ��ʽ�������붨��һ���ٽ��������������һ����̬ΪCRITICAL_SECTION��������������磺

CRITICAL_SECTION cs ;

���CRITICAL_SECTION������̬��һ���ṹ���������е���λֻ����Windows�ڲ�ʹ�á�����ٽ�������������ȱ���ʽ�е�ij��ִ������ʼ����ͨ�����У�

InitializeCriticalSection (&cs) ;

�����ͽ�����һ����Ϊcs���ٽ�����������ú�ʽ�����ϸ���˵����������ľ��棺���ٽ�����������ܱ��ƶ����߸��ƣ�����Ҳ�����޸ĸ���������������߼��ϰ�����Ϊ��͸���ġ�����仰�����Ա�����Ϊ������Ҫ��������������Ҫ��������

���ٽ������������ʼ��֮�ᣬִ��������ͨ������ĺ��н����ٽ�����

EnterCriticalSection (&cs) ;

����ʱ��ִ��������Ϊ��ӵ�С��ٽ��������������ִ����������ͬʱӵ��ͬһ���ٽ������������ˣ����һ��ִ�����������ٽ�������ô��һ��ʹ��ͬһ�ٽ������������EnterCriticalSection��ִ�������ں�ʽ�����б���ͣ��ֻ�е���һ��ִ����ͨ������ĺ����뿪�ٽ�����ʱ����ʽ�Żᴫ�ؿ���Ȩ��

LeaveCriticalSection (&cs) ;

��ʱ����EnterCriticalSection�����б�ͣס���Ǹ�ִ������ӵ���ٽ������亯ʽ����Ҳ�����أ�����ִ��������ִ�С�

���ٽ������ٱ���ʽ����Ҫʱ������ͨ������

DeleteCriticalSection (&cs) ;

����ɾ�����ú�ʽ�ͷ����б�������ά�����ٽ����������ϵͳ��Դ��

�����ٽ��������漰�����⡹�������������Ǽ�������ִ����ͬ��ʱ���ٴγ��֣������κ�ʱ�̣�ֻ��һ��ִ������ӵ��һ���ٽ�������ˣ�һ��ִ�������Խ���һ���ٽ������趨һ���ṹ����λ��Ȼ���˳��ٽ�������һ��ʹ�øýṹ��ִ�����ڴ�ȡ�ṹ�е���λ֮ǰҲҪ�Ƚ�����ٽ�����Ȼ�����˳��ٽ�����

ע�⣬�����Զ������ٽ��������������cs1��cs2�����磬���һ����ʽ���ĸ�ִ��������ǰ����ִ��������һЩ���ϣ���ô���ǿ���ʹ��һ���ٽ��������������������ִ��������һЩ���������ϣ���ô���ǿ���ʹ����һ���ٽ����������

������ִ������ʹ���ٽ�����ʱӦ��С�ġ��������ִ���������Լ����ٽ������л�����һ�κܳ���ʱ�䣬��ô�����ܻὫ��ִ������ִ���谭�ܳ�һ��ʱ�䡣����ִ��������ֻ��ʹ���ٽ������Ƹýṹ����λ���Լ�����������С�

�ٽ������һ������������ֻ�������ͬһ�����ڵ�ִ����֮���Э����������ijЩ����£�����ҪЭ��������ͬ�����ͬһ��Դ�Ĺ��ã��繲�ü�����ȣ����ڴ�����²���ʹ���ٽ����򣬵��ǿ���ʹ��һ�ֱ���Ϊ�����������mutex object�����ļ�������mutex���Ǹ��ϳ��֣�������mutual exclusion�����⣩�����������ᆱȷ�ر��������ǵ�Ŀ�ġ��������ֹһ����ʽ��ִ�����ڸ������ϻ���ʹ�ù��ü�������������Դʱ���жϡ�

�¼��ź�
��

��ִ����ͨ���������Щ����ִ�г�ʱ�䴦���ij�ʽ�����ǿ��Խ�һ��������ҵ������Ϊһ�����ܻ�Υ��1/10�����ij�ʽ����Ȼ����ҵ�������鴦����ʽ�е�ƴд��顢���Ͽ��ʽ�еĵ��������������������������¼��㡢��ӡ�������������ӵĻ�ͼ����Ȼ������Ϊֹ����֪������ѭ1/10��������÷����ǽ�����ҵ�ŵ���һ��ִ����ȥִ�С���Щ�����ִ�������Ὠ���Ӵ���������Dz���1/10���������ơ�

ͨ��ϣ����Щ�����ִ���������������ʱ�ܹ�֪ͨ��ִ������������ִ�����ܹ�ֹͣ����ִ�������ڽ��е���ҵ��������������潫Ҫ���۵ġ�

BIGJOB1��ʽ
��

��Ϊһ������Ĵ���ҵ���ҽ�ʹ��һϵ�и������㣬��ʱ�������㱻��Ϊ�������ġ����ܲ���ָ�ꡣ���ּ�����һ�ּ�ӵķ�ʽ����һ��������ֵ������һ������ƽ�����ٶԽ��ȡƽ�������õ�ԭ������������Ȼ��ʹ��log��exp��ʽ��ͬ���õ�ԭ����������������ʹ��atan��tan��ʽ�����ǵõ�ԭ����������������Խ����1��

BIGJOB1��ʽ���ʽ20-4��ʾ��

 ï¿½ï¿½Ê½20-4  BIGJOB1
BIGJOB1.C
/*---------------------------------------------------------------------------
   	BIGJOB1.C -- Multithreading Demo
                						(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#include <windows.h>
#include <math.h>
#include <process.h>

#define REP              						1000000

#define STATUS_READY     			0
#define STATUS_WORKING   		    1
#define STATUS_DONE      			2

#define WM_CALC_DONE     		(WM_USER + 0)
#define WM_CALC_ABORTED  		(WM_USER + 1)

typedef struct
{
     	HWND hwnd ;
     	BOOL bContinue ;
}
PARAMS, *PPARAMS ;
LRESULT APIENTRY WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    szCmdLine, int iCmdShow)
{
     	static TCHAR 		szAppName[] = TEXT ("BigJob1") ;
     	HWND         					hwnd ;
     	MSG          					msg ;
     	WNDCLASS     				wndclass ;
     	wndclass.style         		= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   		= WndProc ;
     	wndclass.cbClsExtra    		= 0 ;
     	wndclass.cbWndExtra    		= 0 ;
     	wndclass.hInstance     		= hInstance ;
     	wndclass.hIcon         		= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       	= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  	= NULL ;
     	wndclass.lpszClassName 	= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
        MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      	szAppName, MB_ICONERROR) ;
          		return 0 ;
     }
     
     	hwnd = CreateWindow (	szAppName, TEXT ("Multithreading Demo"),
                          		WS_OVERLAPPEDWINDOW,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

void Thread (PVOID pvoid)
{
     	double   		A = 1.0 ;
     	INT      			i ;
     	LONG     			lTime ;
     	volatile		PPARAMS pparams ;
     
     	pparams = (PPARAMS) pvoid ;
     	lTime = GetCurrentTime () ;
     	for (i = 0 ; i < REP && pparams->bContinue ; i++)
          				A = tan (atan (exp (log (sqrt (A * A))))) + 1.0 ;
     	if (i == REP)
     	{
          		lTime = GetCurrentTime () - lTime ;
          		SendMessage (pparams->hwnd, WM_CALC_DONE, 0, lTime) ;
   	}
     	else
          		SendMessage (pparams->hwnd, WM_CALC_ABORTED, 0, 0) ;
     	_endthread () ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static 	INT  		iStatus ;
     	static 	LONG 		lTime ;
     	static 	PARAMS	params ;
     	static 		TCHAR *	szMessage[] = { TEXT ("Ready (left mouse button begins)"),
                    TEXT ("Working (right mouse button ends)"),
                    TEXT ("%d repetitions in %ld msec") } ;
     	HDC            					hdc ;
     	PAINTSTRUCT    			        ps ;
     	RECT           					rect ;
     	TCHAR          					szBuffer[64] ;
     
     	switch (message)
     	{
     	case 	WM_LBUTTONDOWN:
          			if (iStatus == STATUS_WORKING)
          			{
               				MessageBeep (0) ;
               				return 0 ;
          			}
          
          			iStatus = STATUS_WORKING ;
          
          			params.hwnd = hwnd ;
          			params.bContinue = TRUE ;
          
          			_beginthread (Thread, 0, ¶ms) ;
          
          			InvalidateRect (hwnd, NULL, TRUE) ;
          			return 0 ;
         
     	case 	WM_RBUTTONDOWN:
          			params.bContinue = FALSE ;
          			return 0 ;
          
     	case 	WM_CALC_DONE:
          			lTime = lParam ;
          			iStatus = STATUS_DONE ;
          			InvalidateRect (hwnd, NULL, TRUE) ;
          			return 0 ;
          
     	case 	WM_CALC_ABORTED:
          			iStatus = STATUS_READY ;
          			InvalidateRect (hwnd, NULL, TRUE) ;
          			return 0 ;
          
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          
          			wsprintf (szBuffer, szMessage[iStatus], REP, lTime) ;
          			DrawText (hdc, szBuffer, -1, &rect,
                    		  DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
          
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

����һ���൱�򵥵ij�ʽ����������Ϊ�������������չʾ�ڶ�ִ������ʽ����ɴ���ҵ��ͨ�÷�����Ϊ��ʹ��BIGJOB1��ʽ�����Ӵ�����ʾ�����а��»���������Ӷ���ʼ���������ܲ��Լ����1,000,000���ظ�������һ̨300MHz��Pentium II�����Ͻ�����2�롣����ɼ���ʱ�����ѵ�ʱ�佫��ʾ���Ӵ��ϡ������ڽ��м���ʱ��������ͨ������ʾ�����а��»����Ҽ�����ֹ����

����������һ���������ʵ���ģ�

�Ӵ�ѶϢ������ʽӵ����һ��������iStatus�ľ�̬�������ñ������Ա��趨Ϊ�ڳ�ʽ��ʼ���������������֮һ��������STATUSΪ���ף����ñ�����ʾ��ʽ�Ƿ�׼���ý���һ�μ��㣬�Ƿ����ڽ���һ�μ��㣬�����Ƿ�����˼��㡣��ʽ��WM_PAINTѶϢ�����ڼ�ʹ��iStatus��������ʾ�����������ʾһ���ʵ����ִ���

�Ӵ�ѶϢ������ʽ��ӵ��һ����̬�ṹ����̬ΪPARAMS��Ҳ�����ڳ�ʽ�Ķ��������ýṹ�����Ӵ�ѶϢ������ʽ������ִ����֮��Ĺ������ϡ��ṹֻ��������λ��hwnd����ʽ�Ӵ��Ĵ��ţ���bContinue������һ�����ֱ��������ָʾִ�����Ƿ�����������ֹͣ��

��������ʾ�����а��»������ʱ���Ӵ�ѶϢ������ʽ��iStatus������ΪSTATUS_WORKING�����趨PARAMS�ṹ�е�������λ���ṹ��hwnd��λ���趨Ϊ�Ӵ����ţ���Ȼ��bContinue���趨ΪTRUE��

Ȼ���Ӵ��������_beginthread��ʽ��ִ������ʽThread�Ժ���GetCurrentTime��ʼ��GetCurrentTimeȡ���Ժ���Ƶ�Windows���������Ѿ�ִ���˵�ʱ�䡣Ȼ��������һ��for��Ȧ���ظ�1,000,000�εı������Լ��㡣��Ҫע�⣬���bContinue����Ϊ��FALSE����ôִ�������˳���Ȧ��

��for��Ȧ֮�ᣬִ������ʽ������Ƿ�ȷʵ�����1,000,000�μ��㡣����ǣ���ô���ٴκ���GetCurrentTime�����������ʱ�䣬Ȼ��ʹ��SendMessage���Ӵ�ѶϢ������ʽ����һ���ɳ�ʽ�����WM_USER_DONEѶϢ�����Ծ�����ʱ����ΪlParam�����������������δ���֮ǰ����ֹ�ģ���������ڻ�Ȧ�ڼ�PARAMS�ṹ��bContinue��λ��ΪFALSE������ôִ���������͸��Ӵ�ѶϢ������ʽһ��WM_USER_ABORTEDѶϢ��Ȼ�ᣬִ����ͨ������_endthread�����ؽ�����

���Ӵ�ѶϢ������ʽ�У���������ʾ�����а��»����Ҽ�ʱ��PARAMS�ṹ��bContinue��λ����ΪFALSE�������������ɼ���֮ǰ��������ķ�����

ע��Thread�е�pparams��������Ϊvolatile��������̬�޶����������ָ���������ܻ���ʵ�ʵij�ʽ�����ⱻ�޸ģ����类��һ��ִ��������������ѻ��ı����������pparams->bContinue���ܱ�for��Ȧ�ڵij�ʽ���޸ģ�û�б�Ҫ��ÿ���Ȧ�м�������volatile�ؼ��ַ�ֹ��������ѻ����С�

�Ӵ�ѶϢ������ʽ����WM_USER_DONEѶϢʱ�����ȴ��澭����ʱ�䡣��WM_USER_DONE��WM_USER_ABORTEDѶϢ�Ĵ�������͸����InvalidateRect�ĺ��в���WM_PAINTѶϢ������ʾ������ʾһ���µ��ִ���

�ṩһ����������ṹ�е�bContinue��λ������ִ����������ֹ��ͨ����һ�������⡣KillThread��ʽֻ����������ִֹ�����Ƚ�����ʱ��Ӧ��ʹ�ã�ԭ����ִ��������������Դ���������ȡ������ִ������ֹʱû���ͷ������õļ����壬��ô�����彫��Ȼ�DZ������˵ġ�ִ�������dz��������õ���Դ��һ�����������ִ����֮���ǹ��õģ���˵�ִ������ֹʱ����Դ���ᱻ�Զ��ͷš��õij�ʽ�ṹҪ��һ��ִ�����ͷ��������õ�������Դ��

����Ӧ��֪�����ڶ���ִ��������ִ��ʱ�����Խ���������ִ���������Windows��SendMessage���к�_endthread����֮�䣬������Ȩ�ӵڶ���ִ�����л�����һ��ִ��������ô�Ӵ�ѶϢ������ʽ�Ϳ��ܻ�Ӧ���󰴼�������һ���µ�ִ�������Ӷ�������������������ⲻ��ʲô���⣬�������������Լ���Ӧ����˵��һ������Ļ�����ô�����ܻῼ��ʹ���ٽ�����������ִ����֮��ij�ͻ��

�¼����
��

BIGJOB1��ÿ����Ҫִ�б������Լ���ʱ���ͽ���һ��ִ������ִ��������ɼ���֮���Զ���ֹ��

��һ�ֿ��õķ������ڳ�ʽ���������������ڱ���ִ������ִ�У�����ֻ�ڱ�Ҫʱ��������������һ��Ӧ���¼���������������

�¼���������ǡ����źŵġ���Ҳ��Ϊ���������ġ�����û�źŵġ���Ҳ��Ϊ�������õġ�����������ͨ����������������¼������

hEvent = CreateEvent (&sa, fManual, fInitial, pszName) ;

��һ��������ָ��һ��SECURITY_ATTRIBUTES�ṹ��ָ�꣩������һ��������һ���¼���������֣�ֻ�����¼���������������ʱ�������塣��ͬһ�����У���Щ����ͨ�����趨ΪNULL�������ϣ���¼��������ʼ��Ϊ���źŵģ���ô��fInitial�����趨ΪTRUE�������ϣ���¼��������ʼ��Ϊ���źŵģ���fInitial�����趨ΪFALSE�����ᣬ�ҽ���̵�����fManual������

Ҫ����һ���ִ���¼����������

SetEvent (hEvent) ;

Ҫ����һ���¼����������

ResetEvent (hEvent) ;

һ����ʽͨ�����У�

WaitForSingleObject (hEvent, dwTimeOut) ;

���ҽ��ڶ��������趨ΪINFINITE������¼����Ŀǰ�DZ������ģ���ô��ʽ���������أ����򣬺�ʽ����ִͣ����ֱ���¼��������������������ڶ��������趨Ϊһ���Ժ���Ƶij�ʱʱ��ֵ��������ʽҲ�������¼����������֮ǰ���ء�

��������CreateEvent���е�fManual�������趨ΪFALSE����ô�¼��������WaitForSingleObject��ʽ����ʱ�Զ����á����ֹ�������ͨ��ʹ���¼����û�б�Ҫʹ��ResetEvent��ʽ��

���ڣ����ǿ�������һ����ʽ20-5��ʾ��BIGJOB2.C��ʽ��

 ï¿½ï¿½Ê½20-5  BIGJOB2
BIGJOB2.C
/*----------------------------------------------------------------------------
   	BIGJOB2.C -- Multithreading Demo
                						(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
#include <math.h>
#include <process.h>

#define REP              						1000000

#define STATUS_READY     			0
#define STATUS_WORKING   		    1
#define STATUS_DONE      			2

#define WM_CALC_DONE     			(WM_USER + 0)
#define WM_CALC_ABORTED  		    (WM_USER + 1)

typedef struct
{
     	HWND   			hwnd ;
     	HANDLE 		    hEvent ;
     	BOOL   			bContinue ;
}
PARAMS, *PPARAMS ;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("BigJob2") ;
     	HWND         				hwnd ;
     	MSG          				msg ;
	WNDCLASS     				wndclass ;

     	wndclass.style         		= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   		= WndProc ;
     	wndclass.cbClsExtra    		= 0 ;
     	wndclass.cbWndExtra    		= 0 ;
     	wndclass.hInstance    	 	= hInstance ;
     	wndclass.hIcon         	= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       	= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  	= NULL ;
     	wndclass.lpszClassName 	= szAppName ;
     
     	if (!RegisterClass (&wndclass))
	{
       MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                    szAppName, MB_ICONERROR) ;
          		return 0 ;
     }
     
     	hwnd = CreateWindow (	szAppName, TEXT ("Multithreading Demo"),
                          		WS_OVERLAPPEDWINDOW,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

void Thread (PVOID pvoid)
{
     	double   		A = 1.0 ;
     	INT      			i ;
     	LONG     			lTime ;
     	volatile 		PPARAMS pparams ;
     
     	pparams = (PPARAMS) pvoid ;
     	while (TRUE)
     	{
          		WaitForSingleObject (pparams->hEvent, INFINITE) ;
          		lTime = GetCurrentTime () ;
          		for (i = 0 ; i < REP && pparams->bContinue ; i++)
               				A = tan (atan (exp (log (sqrt (A * A))))) + 1.0 ;
          		if (i == REP)
          		{
               				lTime = GetCurrentTime () - lTime ;
               				PostMessage (pparams->hwnd, WM_CALC_DONE, 0, lTime) ;
          		}
          		else
               				PostMessage (pparams->hwnd, WM_CALC_ABORTED, 0, 0) ;
     	}
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static 	HANDLE  	hEvent ;
     	static 	INT     	iStatus ;
     	static 	LONG    	lTime ;
     	static 	PARAMS 	params ;
     	static 		TCHAR *	szMessage[] = { TEXT ("Ready (left mouse button begins)"),
                    TEXT ("Working (right mouse button ends)"),
                    TEXT ("%d repetitions in %ld msec") } ;
     	HDC            					hdc ;
     	PAINTSTRUCT    			        ps ;
     	RECT           					rect ;
     	TCHAR          					szBuffer[64] ;
     
     	switch (message)
     	{
     	case 	WM_CREATE:
          			hEvent = CreateEvent (NULL, FALSE, FALSE, NULL) ;
          
          			params.hwnd = hwnd ;
          			params.hEvent = hEvent ;
          			params.bContinue = FALSE ;
          
          			_beginthread (Thread, 0, ¶ms) ;
          
          			return 0 ;
          
 	case 	WM_LBUTTONDOWN:
          			if (iStatus == STATUS_WORKING)
          			{
               				MessageBeep (0) ;
               				return 0 ;
          			}
          			iStatus = STATUS_WORKING ;
          			params.bContinue = TRUE ;
          
          			SetEvent (hEvent) ;
        
          			InvalidateRect (hwnd, NULL, TRUE) ;
          			return 0 ;
          
     	case 	WM_RBUTTONDOWN:
          			params.bContinue = FALSE ;
          			return 0 ;
          
     	case 	WM_CALC_DONE:
          			lTime = lParam ;
          			iStatus = STATUS_DONE ;
          			InvalidateRect (hwnd, NULL, TRUE) ;
          			return 0 ;
          
     	case 	WM_CALC_ABORTED:
          			iStatus = STATUS_READY ;
          			InvalidateRect (hwnd, NULL, TRUE) ;
          			return 0 ;
          
 	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          
          			wsprintf (	szBuffer, szMessage[iStatus], REP, lTime) ;
          			DrawText (	hdc, szBuffer, -1, &rect,
                    							DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
          
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

����WM_CREATEѶϢʱ���Ӵ�ѶϢ������ʽ���Ƚ���һ����ʼ��Ϊû�źŵ��Զ������¼������Ȼ�Ὠ��ִ������

Thread��ʽ����һ�����޵�while��Ȧ���ڻ�Ȧ��ʼʱ���Ⱥ���WaitForSingleObject��ע��PARAMS�ṹ����һ�������¼�������ŵ���λ������Ϊ�¼�����ʼ��Ϊ���õģ�����ִ������ִ�б��赲�ں�ʽ�����С����»�������������Ӵ��������SetEvent���⽫�ͷ���WaitForSingleObject���в����ĵڶ���ִ����������ʼ�������Լ��㡣��������֮�ᣬִ�����ٴκ���WaitForSingleObject��������춵�һ�κ����Ѿ�ʹ�¼�������ã���ˣ�ִ����������ͣ��ֱ���ٴΰ��»���

���������棬��ʽ������BIGJOB1��ȫһ����

ִ�������򴢴�ռ䣨TLS��
��

��ִ������ʽ�е�����������Լ��κα����õļ����壩����ʽ�е�����ִ�������á���һ����ʽ�еľֲ���̬����Ҳ��ʹ�ú�ʽ������ִ�������á�һ����ʽ�еľֲ���̬������Ψһ춸���ִ�����ģ���Ϊ���DZ������ڶѵ��ϣ���ÿ��ִ���������Լ��Ķѵ���

�Ը���ִ����Ψһ�ij����Դ���ռ��д��ڵı�Ҫ�����磬���ڱ���ǰ���ᵽ����C�е�strtok��ʽҪ��������̬�Ĵ���ռ䡣���ҵ��ǣ�C���Բ�֧Ԯ���ഢ��ռ䡣����Windows���ṩ���ĸ���ʽ������ʵ����һ�ּ�����������һ�㣬����Microsoft��C�������﷨Ҳ֧Ԯ������ͽ���ִ�������򴢴�ռ䡣

������API�����ķ�����

���ȣ�����һ��������ҪΨһ�ִ�������������ϵĽṹ�����磺

typedef struct
{
     	int a ;
     	int b ;
}
DATA, * PDATA ;

��ִ��������TlsAlloc���һ������ֵ��

dwTlsIndex = TlsAlloc () ;

���ֵ���Դ�����һ����������л���ͨ�������ṹ���ݸ�ִ������ʽ��

ִ������ʽ����Ϊ�����Ͻṹ���ü����壬��ʹ����������õ�����ֵ����TlsSetValue��

TlsSetValue (dwTlsIndex, GlobalAlloc (GPTR, sizeof (DATA)) ;

�ú�ʽ��һ��ָ���ij��ִ������ij��ִ������������������ڣ��κ���Ҫʹ�����ָ��ĺ�ʽ�����������ִ������ʽ�����������԰���������ʾ�ij�ʽ�룺

PDATA pdata ;
...
pdata = (PDATA) TlsGetValue (dwTlsIndex) ;

���ں�ʽ�����趨����ʹ��pdata->a��pdata->b�ˡ���ִ������ʽ��ֹ��ǰ�����ͷ����õļ����壺

GlobalFree (TlsGetValue (dwTlsIndex)) ;

��ʹ�ø����ϵ�����ִ��������ֹ֮ʱ����ִ�������ͷ�������

TlsFree (dwTlsIndex) ;

�������տ�ʼ����������Щ�Ի��������ܿ�һ�����ʵ��ִ�������򴢴�ռ���ܻ��а������Ҳ�֪��Windowsʵ���������ʵ���ģ�������ķ����ǿ��ܵģ������ȣ�TlsAlloc����ֻ������һ������壨����Ϊ0��������һ������ֵ����ָ�����������һ��ָ�ꡣÿ��ʹ�ø���������TlsSetValueʱ��ͨ���������ý������������8��λԪ�顣����8��λԪ���д�����Ǻ��к�ʽ��ִ����ID��ͨ��GetCurrentThreadId����ã��Լ����ݸ�TlsSetValue��ʽ��ָ�ꡣTlsSetValue�򵥵�ʹ��ִ����ID����Ѱ��ҵϵͳ������ִ�������򴢴�ռ�λַ����Ȼ�ᴫ��ָ�ꡣTlsFree���ͷż�����顣�����������������һ�����׵ÿ��������Լ���ʵ�������顣��������Ȼ�Ѿ��й���Ϊ����������Щ��������Ҳ������

Microsoft��C�����书��ʹ��������������ס�ֻҪ��Ҫ��ÿ��ִ������������ͬ���ݵı���ǰ����__declspec (thread)�ͺ��ˡ�����κκ�ʽ���ⲿ��̬��������Ϊ��

__declspec (thread) int iGlobal = 1 ;

��춺�ʽ�ڲ��ľ�̬��������Ϊ��

__declspec (thread) static int iLocal = 2 ;