学习视频链接
目录
- #include
- #include
-
- using namespace std;
-
- // 回调函数
- DWORD WINAPI ThreadProc(PVOID lp)
- {
- int i = 0;
- while (i < 10) {
- Sleep(200);
- i++;
- printf("SubThread: %d\n", i);
- }
- return 0;
- }
-
- int main()
- {
- //CreateThread(NULL, 0, ThreadProc, 0, 0, 0); // 创建,不开启线程
- HANDLE h = CreateThread(NULL, 0, ThreadProc, 0, CREATE_SUSPENDED, 0); // 创建,开启线程
- int i = 10;
- while (i < 20) {
- Sleep(200);
- i++;
- printf("ParentThread: %d\n", i);
- }
-
- ResumeThread(h); // 开启线程
-
- Sleep(3000);
-
- return 0;
- }
h 代表句柄

如果关闭两次线程就需要开启两次线程

- #include
- #include
-
- using namespace std;
-
- int g = 0;
-
- // 回调函数
- DWORD WINAPI ThreadProc(PVOID lp)
- {
- for (int i = 0; i < 1000000; i++) {
- g++;
- }
- return 0;
- }
-
- int main()
- {
- HANDLE h = CreateThread(NULL, 0, ThreadProc, 0, 0, 0);
- for (int i = 0; i < 1000000; i++) {
- g++;
- }
- WaitForSingleObject(h, INFINITE); // 无限等待
- printf("%d\n", g);
- CloseHandle(h); // 关闭线程
-
- return 0;
- }
子线程和主线程可能同时写主线程,导致不能够达到预期的 2000000

- #include
- #include
-
- using namespace std;
-
- unsigned int g = 0;
-
- // 回调函数
- DWORD WINAPI ThreadProc(PVOID lp)
- {
- for (int i = 0; i < 1000000; i++) {
- InterlockedIncrement(&g);
- }
- return 0;
- }
-
- int main()
- {
- HANDLE h = CreateThread(NULL, 0, ThreadProc, 0, 0, 0);
- for (int i = 0; i < 1000000; i++) {
- InterlockedIncrement(&g);
- }
- WaitForSingleObject(h, INFINITE); // 无限等待
- printf("%d\n", g);
- CloseHandle(h); // 关闭线程
-
- return 0;
- }
- #include
- #include
-
- using namespace std;
-
- int g = 0;
- CRITICAL_SECTION g_sec; // 创建临界区对象
-
- // 回调函数
- DWORD WINAPI ThreadProc(PVOID lp)
- {
- for (int i = 0; i < 100000; i++) {
- EnterCriticalSection(&g_sec); // 进入临界区
- g++;
- LeaveCriticalSection(&g_sec);
- }
- return 0;
- }
-
- int main()
- {
- // 初始化临界区对象
- InitializeCriticalSection(&g_sec);
- HANDLE h = CreateThread(0, 0, ThreadProc, 0, 0, 0);
- for (int i = 0; i < 100000; i++) {
- EnterCriticalSection(&g_sec);
- g++;
- LeaveCriticalSection(&g_sec);
- }
- WaitForSingleObject(h, INFINITE); // 无限等待线程执行完
- printf("%d\n", g);
-
- // 句柄释放
- CloseHandle(h);
-
- return 0;
- }
1、内核对象
每一个内核对象在任何时候都处于两种状态之一:信号态和无信号态
线程在等待其中的一个或多个内核对象时,如果在等待的一个或多个内核对象处于无信号态,线程自身将被系统挂起,直到等待的内核对象变为有信号状态时,线程才恢复运行。常用的等待函数有 2 个
2、等待线程函数
在多线程下面,有时候我们会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用 Windows API 函数 WaitForSingleObject,或者 WaitForMultipleObjects。这两个函数都会等待 Object 被标为有信号时才返回的。这两个函数的优点是它们在等待的过程中会进入一个非常高效沉睡状态,只占用极少的 CPU 时间片
(1) 信号
- #include
- #include
-
- using namespace std;
-
- int g = 0;
- HANDLE hmutex;
-
- // 回调函数
- DWORD WINAPI ThreadProc(PVOID lp)
- {
- for (int i = 0; i < 100000; i++) {
- WaitForSingleObject(hmutex, INFINITE); // hmutex 有信号->无信号
- g++;
- ReleaseMutex(hmutex); // hmutex 无信号->有信号
- }
- return 0;
- }
-
- int main()
- {
- // 创建内核对象
- hmutex = CreateMutex(NULL, FALSE, NULL); // hmutex 创建->有信号
- HANDLE h = CreateThread(NULL, 0, ThreadProc, 0, 0, 0);
- for (int i = 0; i < 100000; i++) {
- WaitForSingleObject(hmutex, INFINITE); // hmutex 有信号->无信号
- g++;
- ReleaseMutex(hmutex); // hmutex 无信号->有信号
- }
- WaitForSingleObject(h, INFINITE); // 无限等待线程执行完
- printf("%d\n", g);
-
- // 释放内核释放
- CloseHandle(h);
- CloseHandle(hmutex);
-
- return 0;
- }
(2) 事件
- #include
- #include
-
- using namespace std;
-
- int g = 0;
- HANDLE hEvent;
-
- // 回调函数
- DWORD WINAPI ThreadProc(PVOID lp)
- {
- for (int i = 0; i < 100000; i++) {
- WaitForSingleObject(hEvent, INFINITE); // hmutex 有事件->无事件
- g++;
- SetEvent(hEvent); // hmutex 无事件->有事件
- }
- return 0;
- }
-
- int main()
- {
- // 创建事件对象
- hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
- HANDLE h = CreateThread(NULL, 0, ThreadProc, 0, 0, 0);
- for (int i = 0; i < 100000; i++) {
- WaitForSingleObject(hEvent, INFINITE); // hmutex 有事件->无事件
- g++;
- SetEvent(hEvent); // hmutex 无事件->有事件
- }
- WaitForSingleObject(h, INFINITE); // 无限等待线程执行完
- printf("%d\n", g);
-
- // 释放内核释放
- CloseHandle(h);
- CloseHandle(hEvent);
-
- return 0;
- }
1、使用全局变量进行通信
2、参数传递方式
- #include
- #include
-
- using namespace std;
-
- struct node {
- int age;
- int id;
- };
-
- int g = 0;
- HANDLE hEvent;
-
- // 回调函数
- DWORD WINAPI ThreadProc(PVOID lp)
- {
- node n = *(node*)lp;
- cout << n.age << " " << n.id << endl;;
- for (int i = 0; i < 100000; i++) {
- WaitForSingleObject(hEvent, INFINITE); // hmutex 有事件->无事件
- g++;
- SetEvent(hEvent); // hmutex 无事件->有事件
- }
- return 0;
- }
-
-
-
- int main()
- {
- node n;
- n.id = 1;
- n.age = 10;
- // 创建事件对象
- hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
- HANDLE h = CreateThread(NULL, 0, ThreadProc, &n, 0, 0);
- for (int i = 0; i < 100000; i++) {
- WaitForSingleObject(hEvent, INFINITE); // hmutex 有事件->无事件
- g++;
- SetEvent(hEvent); // hmutex 无事件->有事件
- }
- WaitForSingleObject(h, INFINITE); // 无限等待线程执行完
- printf("%d\n", g);
-
- // 释放内核释放
- CloseHandle(h);
- CloseHandle(hEvent);
-
- return 0;
- }

3、消息传递方式
MFC 里面的
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- TCHAR commandLine[] = TEXT("C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe www.baidu.com");
- _STARTUPINFOW startInfo = { sizeof(_STARTUPINFOW)};
- _PROCESS_INFORMATION processInfo;
- /*
- BOOL CreateProcess(
- LPCTSTR lpApplicationName, 应用程序名称
- LPTSTR lpCommandLine, 命令行字符串
- LPSECURITY_ATTRIBUTES lpProcessAttributes, 进程的安全属性
- LPSECURITY_ATTRIBUTES lpThreadAttributes, 线程的安全属性
- BOOL bInheritHandles, 是否继承父进程的属性
- DWORD dwCreationFlags, 创建标志
- LPVOID lpEnvironment, 指向新的环境块(环境变量)的指针
- LPCTSTR lpCurrentDirectory, 指向当前目录名的指针
- LPSTARTUPINFO lpStartupInfo, 传递给新进程的信息
- LPPROCESS_INFORMATION lpProcessInformation 新进程返回的信息
- );
- */
- bool ret = CreateProcess(NULL, commandLine, NULL, NULL, FALSE, 0, NULL, NULL, &startInfo, &processInfo);
-
- if (ret == false) {
- cout << "创建进程失败" << endl;
- return 0;
- }
- else {
- WaitForSingleObject(processInfo.hProcess, INFINITE);
- cout << "新创建的进程ID: " << processInfo.dwProcessId << endl;
- cout << "新创建的线程ID: " << processInfo.dwThreadId << endl;
- CloseHandle(processInfo.hProcess);
- CloseHandle(processInfo.hThread);
- }
-
- return 0;
- }
上述代码就完成了打开浏览器进程的任务了


>套接字(socket):
套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。
输出字符的程序
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- /*
- HANDLE CreateFileMapping(
- HANDLE hFile, // 物理文件句柄
- LPSECURITY_ATTRIBUTES lpAttributes, // 安全设置
- DWORD flProtect, // 保护设置
- DWORD dwMaximumSizeHigh, // 高位文件大小
- DWORD dwMaximumSizeLow, // 低位文件大小
- LPCTSTR lpName // 共享内存名称
- );
- */
- // 创建共享文件句柄
- HANDLE hMapFile = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, 1024, TEXT("fileMap"));
- char *buf = (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 1024);
-
- gets_s(buf, 100);
-
- while (1) {
- Sleep(1000);
- }
- UnmapViewOfFile(buf);
- CloseHandle(hMapFile);
-
- return 0;
- }
接收字符的程序
- #include
- #include
-
- using namespace std;
-
- int main()
- {
- /*
- HANDLE CreateFileMapping(
- HANDLE hFile, // 物理文件句柄
- LPSECURITY_ATTRIBUTES lpAttributes, // 安全设置
- DWORD flProtect, // 保护设置
- DWORD dwMaximumSizeHigh, // 高位文件大小
- DWORD dwMaximumSizeLow, // 低位文件大小
- LPCTSTR lpName // 共享内存名称
- );
- */
- // 创建共享文件句柄
- HANDLE hMapFile = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, 1024, TEXT("fileMap"));
- char *buf = (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 1024);
-
- cout << buf << endl;
-
- getchar();
- UnmapViewOfFile(buf);
- CloseHandle(hMapFile);
-
- return 0;
- }