�������� Linux Tags
20. �๤�Ͷ�ִ����
�๤������ʲô�µĶ������ڴ��͵����ϣ��๤�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������������û�б����������ô�����������������Ȼ��Ҫ���һ�����Ƿ�����������Ҫ��ʹ��С춱������������������������������������ֻ��ʹ������С춱��������ƽ����������ƽ���������Ƿ�����������Ô�ò£¬·ï¿½ï¿½ò£¬¸Ã³ï¿½Ê½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½È«ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ä³ï¿½Ê½ï¿½ï¿½
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�ʽҲ�ƺ����Զ�������ִ�У����ǿ��ܻᷢ��һЩ���⡣���磬������ʽ���ܻ���Ҫͬʱ��ͬһ�������ж����߶�ͬһ��������д������������£���ҵϵͳ�ṩ��һ�ֹ��õ����ͼ�¼�����ļ������������������⡣
Ȼ������֧Ԯ��ִ��������ҵϵͳ�У�������û��Ҷ��Ҵ���DZ�ڵ�Σ�ա���������ִ��������ijЩ���ϵ�����������������磬һ��ִ�������Ը���һ�����߶������������һ��ִ��������ʹ����Щ��������ʱ�������һ�����⣬��ʱ�ֲ��ᣨ��ס��ҵϵͳ������Ȩ��һ��ִ�����л�����һ��ִ�����IJ�����ֻ���ڻ�����ָ��֮�䷢�������ֻ��һ��������ִ�������ã���ô����������ĸı�ͨ�������ڵ���ָ���У����DZ�ڵ����ⱻ��С���ˣ���
Ȼ��������ִ�������ü��������������Ͻṹ��ͨ������ô����������߽ṹ����λ������֮�������һ�µġ���ҵϵͳ�����ڸ�����Щ�����ij����м��ж�һ��ִ��������ôʹ����Щ������ִ�����õ��Ľ��Dz�һ�µ����ϡ�
����dz�ͻ�����ˣ�����ͨ���������������Ĵ��󽫶Գ�ʽ����������ƻ�����������Ҫ��������춺��̵Ƶ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 ;