标签:number ase 重置 attribute 大于 long 最大值 leo nap
WINBASEAPI
VOID
WINAPI
InitializeCriticalSection(
_Out_ LPCRITICAL_SECTION lpCriticalSection
);
WINBASEAPI
VOID
WINAPI
DeleteCriticalSection(
_Inout_ LPCRITICAL_SECTION lpCriticalSection
);
WINBASEAPI
VOID
WINAPI
LeaveCriticalSection(
_Inout_ LPCRITICAL_SECTION lpCriticalSection
);
/*用3个线程共同把nSum累加到240*/
#include <cstdio>
#include <Windows.h>
#define INF 0x7fffffff
//全局变量
int nSum = 0;
const int NUMBER = 80;
//累加线程函数
DWORD WINAPI Accumulate(LPVOID lpParam) {
for (int i = 0; i < NUMBER; i++) {
//多个线程同时就绪,让nSum不唯一
int iCopy = nSum;
nSum = iCopy + 1;
}
return 0;
}
int main() {
HANDLE hThread[3];
hThread[0] = CreateThread(nullptr, 0, Accumulate, nullptr, 0, nullptr);
hThread[1] = CreateThread(nullptr, 0, Accumulate, nullptr, 0, nullptr);
hThread[2] = CreateThread(nullptr, 0, Accumulate, nullptr, 0, nullptr);
//等待这三个线程结束之后才能返回
WaitForMultipleObjects(3, hThread, true, INF);
printf("nSum = %d\n", nSum);
system("pause");
return EXIT_SUCCESS;
}
结果可能会出现不是240的情况
功能:等待目标对象变成有信号的状态返回
WINBASEAPI
DWORD
WINAPI
WaitForMultipleObjects(
_In_ DWORD nCount, // 等待的目标对象的数量
_In_reads_(nCount) CONST HANDLE* lpHandles, // 目标对象的句柄
_In_ BOOL bWaitAll, // 等待方式
_In_ DWORD dwMilliseconds // 等待时间,单位是毫秒
);
等待单个对象:
WINBASEAPI
DWORD
WINAPI
WaitForSingleObject(
_In_ HANDLE hHandle, // 等待的目标对象的句柄
_In_ DWORD dwMilliseconds // 等待时间,单位是毫秒
);
/*用3个线程共同把nSum累加到240*/
#include <cstdio>
#include <Windows.h>
#define INF 0x7fffffff
//全局变量
int nSum = 0;
const int NUMBER = 80;
//定义临界区对象
CRITICAL_SECTION cs;
//累加线程函数
DWORD WINAPI Accumulate(LPVOID lpParam) {
for (int i = 0; i < NUMBER; i++) {
//进入临界区 P(S)
EnterCriticalSection(&cs);
//多个线程同时就绪,让nSum不唯一
int iCopy = nSum;
nSum = iCopy + 1;
//退出临界区 V(S)
LeaveCriticalSection(&cs);
}
return 0;
}
int main() {
//初始化临界区对象
InitializeCriticalSection(&cs);
HANDLE hThread[3];
hThread[0] = CreateThread(nullptr, 0, Accumulate, nullptr, 0, nullptr);
hThread[1] = CreateThread(nullptr, 0, Accumulate, nullptr, 0, nullptr);
hThread[2] = CreateThread(nullptr, 0, Accumulate, nullptr, 0, nullptr);
//等待这三个线程结束之后才能返回
WaitForMultipleObjects(3, hThread, true, INF);
printf("nSum = %d\n", nSum);
system("pause");
return EXIT_SUCCESS;
}
//创建互斥量
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateMutexW(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner, //初始化互斥量的状态:真或假
_In_opt_ LPCWSTR lpName //名字,可为null但不能跨进程用
);
//打开一个存在的互斥量
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
OpenMutexW(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ LPCWSTR lpName //名字
);
WINBASEAPI
BOOL
WINAPI
ReleaseMutex(
_In_ HANDLE hMutex
);
//关闭互斥量
WINBASEAPI
BOOL
WINAPI
CloseHandle(
_In_ _Post_ptr_invalid_ HANDLE hObject //句柄
);
//创建信号量
WINBASEAPI
HANDLE
WINAPI
CreateSemaphoreW(
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //安全属性
_In_ LONG lInitialCount, //初始值
_In_ LONG lMaximumCount, //最大值
_In_opt_ LPCWSTR lpName //名字
);
//打开信号量
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
OpenSemaphoreW(
_In_ DWORD dwDesiredAccess, //存取方式
_In_ BOOL bInheritHandle, //能否被继承
_In_ LPCWSTR lpName //名字
);
//释放信号量
WINBASEAPI
BOOL
WINAPI
ReleaseSemaphore(
_In_ HANDLE hSemaphore, //句柄
_In_ LONG lReleaseCount, //释放数,使信号量的值增加的数量
_Out_opt_ LPLONG lpPreviousCount //得到释放前信号量的值
);
//关闭信号量
WINBASEAPI
BOOL
WINAPI
CloseHandle(
_In_ _Post_ptr_invalid_ HANDLE hObject //句柄
);
#include <cstdio>
#include <Windows.h>
#define INF 0x7fffffff
//线程函数
DWORD AcessDB(void* pD) {
HANDLE hSu = OpenSemaphore(SEMAPHORE_ALL_ACCESS, (LPWSTR)L"SU");
while (true) {
WaitForSingleObject(hSu, INF);
//此处时模拟数据库访问
printf("Do database access!\n");
Sleep(100);
ReleaseSemaphore(hSu, 1, nullptr);
}
}
int main() {
//创建信号灯
HANDLE hSU = nullptr;
//功能:信号量初始值为2,保证最多只有2个线程可以同时进行数据库访问
hSU = CreateSemaphore(nullptr, 2, 2, (LPWSTR)L"SU");
//创建三个线程
HANDLE hThread[3];
CWinThread* pT1 = AfxBeginThread(AccessDB, (void*)1);
CWinThread* pT2 = AfxBeginThread(AccessDB, (void*)2);
CWinThread* pT3 = AfxBeginThread(AccessDB, (void*)3);
hThread[0] = pT1->m_hThread;
hThread[1] = pT2->m_hThread;
hThread[2] = pT3->m_hThread;
WaitForMultipleObjects(3, hThread, true, INF);
//关闭句柄
CloseHandle(hSU);
return EXIT_SUCCESS;
}
用于通知一个或多个线程某事件出现或某操作已经完成
临界区对象 | |
---|---|
EnterCriticalSection(); | P操作 |
LeaveCriticalSection(); | V操作 |
互斥量对象 | |
ReleaseMutex() | V操作 |
事件对象 | |
Bool SetEvent() | V操作 |
信号量对象 | |
CreateSemaphore() | |
ReleaseSemaphore() | V操作 |
等待机制 | |
WaitForSingleObject() | P操作 |
/*
先运行子进程,打印子进程的pid,然后返回父进程,父进程打印返回回来的子进程的pid
*/
#include <iostream>
#include <unistd.h>
int main() {
pid_t pid, pid_1, pid_2;
pid = fork();
// 子进程
if (pid == 0) {
pid_1 = getpid();
printf("pid1 = %d \n", pid_1);
sleep(10);
}
// 父进程
if (pid > 0) {
// 返回子进程的id号
// 子进程运行结束后,进入僵尸态,父进程来进行善后工作-
pid_2 = wait(nullptr);
printf("pid2 = %d\n", pid_2);
}
exit(0);
}
进程调用wait(int status)会阻塞自己
父进程调用wait函数做善后工作
#include <iostream>
#include <unistd.h>
int main() {
pid_t pid;
int i = 1;
// 创建新进程
pid = fork();
// 子进程
if (pid == 0) {
i = 2;
printf("In child i = %d\n", i);
exit(0);
} else {
// 十秒休眠,让子进程先执行
sleep(10);
printf("In parent i = %d\n", i);
exit(0);
}
}
结论:对于普通变量,父子进程各自操作变量副本,互相不影响
对于文件,父子进程共享同一文件和读写指针
【av68676164(p31-p32)】Windows和Linux同步机制
标签:number ase 重置 attribute 大于 long 最大值 leo nap
原文地址:https://www.cnblogs.com/iamfatotaku/p/12590302.html