// 新建一个win32项目,因为要使用系统提供的API函数创建多线程 // win32控制台不能使用系统的API函数 #include "stdafx.h" //控制台项目 #include "windows.h" #include "winbase.h" #include <process.h> #include <iostream> using namespace std; // 构造函数不是线程安全函数 class Singelton { private: Singelton() { cout << "Singelton构造函数Begin" << endl; //Sleep(1000); //睡眠 cout << "Singelton构造函数End" << endl; } public: static Singelton *getSingelton() { if (single == NULL) //需要判断 { count++; single = new Singelton(); } return single; } static Singelton *releaseSingelton() { if (single != NULL) //需要判断 { delete single; single = NULL; } return single; } static void pirntS() //测试函数 { cout << "Singelton printS test" << endl; } private: static Singelton *single; static int count; }; //静态变量类外初始化 Singelton *Singelton::single = NULL; // 懒汉式 int Singelton::count = 0; void main11() { Singelton *s1 = Singelton::getSingelton(); Singelton *s2 = Singelton::getSingelton(); if (s1 == s2) { cout << "ok....equal" << endl; } else { cout << "not...equal" << endl; } } void MyThreadFunc(void *) { //cout << "我是线程体 ...." << endl; //cout << endl; 等价于: cout << '\n' << flush;刷新缓冲区 cout << "我是线程体 ....\n"; Singelton::getSingelton()->pirntS(); } int _tmain(int argc, _TCHAR* argv[]) { //main11(); HANDLE hThread[10]; for (int i = 0; i<3; i++) //在主进程创建三个线程 { hThread[i] = (HANDLE)_beginthread(MyThreadFunc, 0, NULL); } for (int i = 0; i<3; i++) //监控所有的子线程结束 { WaitForSingleObject(hThread[i], INFINITE); } return 0; }从上例的运行结果看,Singelton()的构造函数执行了三次,不再是单例!
小插曲:——endl和"\n"的区别:
在MyThreadFunc()函数中,cout << "我是线程体 ...." << endl; //cout << endl; 等价于: cout << '\n' << flush;endl刷新缓冲区;。而cout << "我是线程体 ....\n";在C++里\n不刷新缓冲区。void main() { int n = 10; cout << n << '\n'; //operator <<(ostream&, char) cout << n << "\n"; //operator <<(ostream&, const char *) cout << n << endl; /* inline ostream &std::endl(ostream& OutStream) { OutStream.put('\n'); OutStream.flush(); return OutStream; } */ }<<并不是后面跟着什么就直接输出到屏幕什么!cout代表后面的内容输出到 控制台的一个缓冲槽 ,而不是控制台(黑屏幕)。那么缓冲槽在什么情况下会把缓冲槽的内容输出到控制台的“黑屏幕界面”??当遇到endl或者其他fflush之类的命令或函数时,缓冲槽里的内容会按照顺序输出到控制台,再由控制台进行 转义字符 的识别打印。endl会换行、清槽——把缓冲槽里的内容输出到控制台。
//临界区 static CCriticalSection cs; class Singleton { private: Singleton() { m_count ++; TRACE("Singleton begin\n"); Sleep(1000); TRACE("Singleton end\n"); } Singleton(const Singleton &); Singleton& operator = (const Singleton &); public: static void printV() { TRACE("printV..m_count:%d \n", m_count); } static Singleton *Instantialize() { if(pInstance == NULL) //第一次检查 { cs.Lock(); //只有当pInstance等于null时,才开始使用枷锁机制 二次检查 if(pInstance == NULL) //第二次检查 { pInstance = new Singleton(); } cs.Unlock(); } return pInstance; } static Singleton *pInstance; static int m_count; }; Singleton* Singleton::pInstance = NULL; //懒汉式 int Singleton::m_count = 0; ////////////////////////////////////////////////////////////////////////// void threadfunc(void *myIpAdd) { Singleton::Instantialize()->printV(); } void C懒汉式线程同步Dlg::OnBnClickedButton1() //主线程 { int i = 0; DWORD dwThreadId[201], dwThrdParam = 1; HANDLE hThread[201]; int threadnum = 3; for (i=0; i<threadnum; i++) //子线程 { hThread[i] = (HANDLE)_beginthread(&threadfunc, 0 , 0 ); if (hThread[i] == NULL) { TRACE("begin thread %d error!!!\n", i); break; } } for (i=0; i<threadnum; i++) { WaitForSingleObject( hThread[i], INFINITE ); } }