c++线程同步之信号量

// MutexExDlg.h : 头文件
// #pragma once // CMutexExDlg 对话框
class CMutexExDlg : public CDialogEx
{
// 构造
public:
CMutexExDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据
enum { IDD = IDD_MUTEXEX_DIALOG }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
static HANDLE hThread[];
static HANDLE m_Semaphore;
static DWORD WINAPI ThreadProc0(LPVOID lpParameter);
static DWORD WINAPI ThreadProc1(LPVOID lpParameter);
static DWORD WINAPI ThreadProc2(LPVOID lpParameter);
static DWORD WINAPI ThreadProc3(LPVOID lpParameter); // 实现
protected:
HICON m_hIcon; // 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnBnClickedButton1();
static int m_Edit0;
static int m_Edit1;
static int m_Edit2;
static int m_Edit3;
};
// MutexExDlg.cpp : 实现文件
// #include "stdafx.h"
#include "MutexEx.h"
#include "MutexExDlg.h"
#include "afxdialogex.h" #ifdef _DEBUG
#define new DEBUG_NEW
#endif // CMutexExDlg 对话框 CMutexExDlg::CMutexExDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMutexExDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} void CMutexExDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_Edit0);
DDV_MinMaxInt(pDX, m_Edit0, , );
DDX_Text(pDX, IDC_EDIT2, m_Edit1);
DDV_MinMaxInt(pDX, m_Edit1, , );
DDX_Text(pDX, IDC_EDIT3, m_Edit2);
DDV_MinMaxInt(pDX, m_Edit2, , );
DDX_Text(pDX, IDC_EDIT4, m_Edit3);
DDV_MinMaxInt(pDX, m_Edit3, , );
} BEGIN_MESSAGE_MAP(CMutexExDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CMutexExDlg::OnBnClickedButton1)
END_MESSAGE_MAP() // CMutexExDlg 消息处理程序 BOOL CMutexExDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
} // 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。 void CMutexExDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), ); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + ) / ;
int y = (rect.Height() - cyIcon + ) / ; // 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
} //当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMutexExDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
} // 重写虚函数 PreTranslateMessage 屏蔽掉Esc键和Enter键
BOOL CMutexExDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
int keyCode = (int)pMsg->wParam;
if (keyCode == VK_ESCAPE || keyCode == VK_RETURN)
{
return TRUE;
}
}
return CDialogEx::PreTranslateMessage(pMsg);
} HANDLE CMutexExDlg::m_Semaphore = NULL;
int CMutexExDlg::m_Edit0 = ;
int CMutexExDlg::m_Edit1 = ;
int CMutexExDlg::m_Edit2 = ;
int CMutexExDlg::m_Edit3 = ;
HANDLE CMutexExDlg::hThread[] = { NULL }; // 抢红包按钮点击事件处理函数
void CMutexExDlg::OnBnClickedButton1()
{
// 获取编辑框内容到str变量
CString str;
GetDlgItem(IDC_EDIT1)->GetWindowText(str);
// CString 转 int
m_Edit0 = _ttoi(str);
m_Edit1 = ;
m_Edit2 = ;
m_Edit3 = ;
// 这里需要创建一个线程 因为 WaitForMultipleObjects 会阻塞住 另外把this指针作为参数传递给线程,用于子线程更新编辑框内容
HANDLE hThread0 = ::CreateThread(NULL, NULL, ThreadProc0, this, NULL, NULL);
CloseHandle(hThread0);
} DWORD WINAPI CMutexExDlg::ThreadProc0(LPVOID lpParameter)
{
CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter;
// 创建一个信号量
m_Semaphore = ::CreateSemaphore(NULL,
, // 表示初始资源数量,0时不发送信号
, // 表示最大并发数量 lInitialCount < lMaximumCount
NULL);
// 创建三个线程抢红包
hThread[] = ::CreateThread(NULL, NULL, ThreadProc1, lpParameter, NULL, NULL);
hThread[] = ::CreateThread(NULL, NULL, ThreadProc2, lpParameter, NULL, NULL);
hThread[] = ::CreateThread(NULL, NULL, ThreadProc3, lpParameter, NULL, NULL);
// 设置编辑框内容
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT1), L"");
// 将对象设置为已通知状态
ReleaseSemaphore(m_Semaphore,
, // 表示增加个数,必须大于0且不超过最大资源数量
NULL);
// 使用WaitForMultipleObjects监听所有线程,当线程全部结束后,调用CloseHandle关闭句柄.
WaitForMultipleObjects(, hThread, TRUE, -);
::CloseHandle(hThread[]);
::CloseHandle(hThread[]);
::CloseHandle(hThread[]);
::CloseHandle(m_Semaphore);
return ;
} // 线程回调函数1
DWORD WINAPI CMutexExDlg::ThreadProc1(LPVOID lpParameter)
{
CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter;
TCHAR szBuffer[];
DWORD dwTimer = ;
WaitForSingleObject(m_Semaphore, INFINITE);
while (dwTimer < )
{
Sleep();
memset(szBuffer, , );
::GetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), szBuffer, );
swscanf(szBuffer, L"%d", &dwTimer);
dwTimer++;
memset(szBuffer, , );
swprintf(szBuffer, L"%d", dwTimer);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), szBuffer);
}
// 递增信号量的当前资源计数
ReleaseSemaphore(m_Semaphore, , NULL);
return ;
} // 线程回调函数2
DWORD WINAPI CMutexExDlg::ThreadProc2(LPVOID lpParameter)
{
CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter;
TCHAR szBuffer[];
DWORD dwTimer = ;
WaitForSingleObject(m_Semaphore, INFINITE);
while (dwTimer < )
{
Sleep();
memset(szBuffer, , );
::GetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT3), szBuffer, );
// 将TCHAR* 转换为 int
swscanf(szBuffer, L"%d", &dwTimer);
dwTimer++;
memset(szBuffer, , );
// int 转换为TCHAR*
swprintf(szBuffer, L"%d", dwTimer);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT3), szBuffer);
}
// 递增信号量的当前资源计数
ReleaseSemaphore(m_Semaphore, , NULL);
return ;
} // 线程回调函数3
DWORD WINAPI CMutexExDlg::ThreadProc3(LPVOID lpParameter)
{
CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter;
TCHAR szBuffer[];
DWORD dwTimer = ;
WaitForSingleObject(m_Semaphore, INFINITE);
while (dwTimer < )
{
Sleep();
memset(szBuffer, , );
::GetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT4), szBuffer, );
swscanf(szBuffer, L"%d", &dwTimer);
dwTimer++;
memset(szBuffer, , );
swprintf(szBuffer, L"%d", dwTimer);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT4), szBuffer);
}
// 递增信号量的当前资源计数
ReleaseSemaphore(m_Semaphore, , NULL);
return ;
}
c++线程同步之信号量的更多相关文章
- Python并行编程(五):线程同步之信号量
1.基本概念 信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用.本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取. 同样在threading中,信号 ...
- 线程同步、信号量、system v IPC
一.线程同步 条件变量 什么是条件变量? 线程A等待某个条件成立,条件成立,线程A才继续向下执行.线程B的执行使条件成立,条件成立以后唤醒线程A,以继续执行.这个条件就是条件变量. pthread_c ...
- 线程同步之信号量(sem_init,sem_post,sem_wait)
信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区. 不多做解释,要使用信号量同步,需要包含头文件semaphore.h. 主要用到的函数: int ...
- Python 线程同步锁, 信号量
同步锁 import time, threading def addNum(): global num num -= 1 num = 100 thread_list = [] for i in ran ...
- [b0032] python 归纳 (十七)_线程同步_信号量Semaphore
代码: # -*- coding: utf-8 -*- """ 多线程并发同步 ,使用信号量threading.Semaphore 逻辑: 多个线程,对同一个共享变量 , ...
- Java多线程—线程同步(单信号量互斥)
JDK中Thread.State类的几种状态 线程的生命周期 线程的安全问题(同步与互斥) 方法一:同步代码块 多个线程的同步监视器(锁)必须的是同一把,任何一个类的对象都可以 syn ...
- 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent
[源码下载] 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEve ...
- windows线程同步的总结
一 线程 1)如果你正在编写C/C++代码,决不应该调用CreateThread.相反,应该使用VisualC++运行期库函数_beginthreadex,退出也应该使用_endthreadex.如果 ...
- C++线程同步的四种方式(Windows)
为什么要进行线程同步? 在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作.更多的情况是一些线程进行某些处理操作,而其他的线程必须对其处理结果进行了解.正常情况下对这种处理结果的 ...
随机推荐
- 导入eclipse有Unbound classpath variable: 'M2_REPO报错的解决方法
Eclipse maven of the project reported in Unbound classpath variable: 'M2_REPO /**/***/***. jar' But ...
- 城东C位之路!探秘三线楼市板块崛起3大核心基因
等着咧!伍家篇什么时候出?这就出. 城东C位之路!- 诸葛磊 好几个粉丝已经在催了,诸葛磊决定改变下写作策略,伍家岗篇分版块用小篇幅来写,这样文章不至于太长,否则又是一篇洋洋洒洒上万字的文章,粉丝看着 ...
- 回顾idea快捷键
F9 resume programe 恢复程序 Alt+F10 show execution point 显示执行断点 F8 Step Over ...
- hive中function函数查询
1. desc function [函数名] desc function xpath; 查询用法: 2. desc function extended [函数名] desc function exte ...
- 最稳定万能vip视频解析接口 支持HTTPS
最稳定万能vip视频解析接口 支持HTTPS https://cdn.yangju.vip/k/?url=后面加上播放的地址即可 https://cdn.yangju.vip/k/?url= http ...
- 报错:ImportError: cannot import name "KafkaProducer" from "kafka"
报错背景: 在Pycharm中安装完成kafka-python之后,我开始在代码中引入kafka的包. from kafka import KafkaProducer 但是引入之后报错 报错现象: 报 ...
- 改进初学者的PID-测量的比例介绍
最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...
- Nginx 反向代理 一个IP代理多个域名,不区分端口,类似windows虚拟机。
简介: IP有限,所以我们以前使用端口来区分不同的虚拟主机,提供不同的WEB服务. 小范围还凑活,一旦规模扩大,地址记不住了吧?端口记不住了吧? 这个时候我们可以使用DNS,域名解析,毕竟记名字比记I ...
- [LeetCode] 381. Insert Delete GetRandom O(1) - Duplicates allowed 插入删除和获得随机数O(1)时间 - 允许重复
Design a data structure that supports all following operations in average O(1) time. Note: Duplicate ...
- js:如何获取select选中的值
我想获取select选中的value,或者text,或者…… 比如这个: <select id="select"> <option value=" ...