很好的控制线程,让线程互斥,互相协调工作,共享数据,这个问题有很多种解决办法,不过我个人觉得使用信号量控制线程特别方便。会想到用多线程控制程序,是由于上学期我们要做一个控制电机转速的课程设计,开始编写的程序都是一个线程控制的。后来课程设计结束了,一次在看多线程的演示程序的时候突然想到,原来的那个电机控制程序完全可以写成多线程,可是由于课程设计结束了,没有硬件供你调试,就自己写了个多线程的练习程序。
控制信号量几个主要的函数:
WaitForSingleObject();//等待信号量有效
CreatSemaphore();//申请信号量
OpenSemaphore();//打开信号量
ReleaseSemaphore();//释放信号量
下面来看看控制多线程要用到的东西:
HANDLE ptrSpdUpDown;
HANDLE ptrUpDownDraw;
HANDLE ptrDrawSpd; //申请指向信号量的句柄
ptrSpdUpDown = ::CreateSemaphore(NULL, 0, 1, NULL);
ptrUpDownDraw = ::CreateSemaphore(NULL, 0, 1, NULL);
ptrDrawSpd = ::CreateSemaphore(NULL, 1, 1, NULL);//实例化三个信号量
bOnOff=true;//线程状态控制量 开启三个线程
m_tWriteSpeed=AfxBeginThread(WriteSpeed,
&m_sWriteSpeed,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
m_tWriteSpeed->ResumeThread();
m_tWriteUpDown=AfxBeginThread(WriteUpDown,
&m_sWriteUpDown,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
m_tWriteUpDown->ResumeThread();
m_tDrawWindow=AfxBeginThread(DrawWindow,
&m_sDrawWindow,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
m_tDrawWindow->ResumeThread();
//三个线程函数
UINT WriteSpeed(LPVOID p)
{
int iNo=1;
CString sTr;
CString sMe;
CEdit *ptr=(CEdit *)p;
while(bOnOff)
{
WaitForSingleObject(ptrDrawSpd,INFINITE);
ptr->SetWindowText("线程WriteSpeed正在运行"+sTr+"---Speed:"+sMe+"已经接到信号");
::Sleep(1000);
srand((int)time(0));//种种子数
iSpeed=iUp+iDown+rand();
ReleaseSemaphore(ptrSpdUpDown,1,NULL);
sTr.Format("%d",iNo);
sMe.Format("%d",iSpeed);
ptr->SetWindowText("线程WriteSpeed正在运行"+sTr+"---Speed:"+sMe);
iNo++;
}
return 0;
}
UINT WriteUpDown(LPVOID p)
{
int iNo=1;
CString sTr;
CString sMe;
CEdit *ptr=(CEdit *)p;
while(bOnOff)
{
WaitForSingleObject(ptrSpdUpDown,INFINITE);
ptr->SetWindowText("线程WriteUpDown正在运行"+sTr+"---Up:"+sMe+"已经接到信号");
::Sleep(1000);
srand((int)time(0));//种种子数
iUp=iSpeed-rand();
iDown=iSpeed+rand();
ReleaseSemaphore(ptrUpDownDraw,1,NULL);
sTr.Format("%d",iNo);
sMe.Format("%d",iUp);
ptr->SetWindowText("线程WriteUpDown正在运行"+sTr+"---Up:"+sMe);
iNo++;
}
return 0;
}
UINT DrawWindow(LPVOID p)
{
int iNo=1;
CString sTr;
CEdit *ptr=(CEdit *)p;
while(bOnOff)
{
WaitForSingleObject(ptrUpDownDraw,INFINITE);
ptr->SetWindowText("线程DrawWindow正在运行"+sTr+"已经接到信号");
::Sleep(1000);
sTr.Format("%d",iNo);
ptr->SetWindowText("线程DrawWindow正在运行"+sTr);
iNo++;
ReleaseSemaphore(ptrDrawSpd,1,NULL);
}
return 0;
}
上面的方法是先申请信号量的句柄然后再实例化信号量 下面这种方法是直接申请信号量 两种方法基本相同
CSemaphore ptrSpdUpDown(0, 1);
CSemaphore ptrUpDownDraw(0, 1);
CSemaphore ptrDrawSpd(1, 1);//#include <atlsync.h>注意在stdafx.h手动包含这个文件
在各个线程函数中不用WaitForSingleObject了要使用Lock()UnLock();
下面是使用CSemaphore后在各个线程函数中使用Lock()UnLock()替换掉WaitForSingleObject的结果
UINT WriteSpeed(LPVOID p)
{
int iNo=1;
CString sTr;
CString sMe;
CEdit *ptr=(CEdit *)p;
while(bOnOff)
{
ptrDrawSpd.Lock();
ptr->SetWindowText("线程WriteSpeed正在运行"+sTr+"---Speed:"+sMe+"已经接到信号");
::Sleep(1000);
srand((int)time(0));//种种子数
iSpeed=iUp+iDown+rand();
ReleaseSemaphore(ptrSpdUpDown,1,NULL);
ptrSpdUpDown.Unlock();
sTr.Format("%d",iNo);
sMe.Format("%d",iSpeed);
ptr->SetWindowText("线程WriteSpeed正在运行"+sTr+"---Speed:"+sMe);
iNo++;
}
return 0;
}
UINT WriteUpDown(LPVOID p)
{
int iNo=1;
CString sTr;
CString sMe;
CEdit *ptr=(CEdit *)p;
while(bOnOff)
{
ptrSpdUpDown.Lock();
ptr->SetWindowText("线程WriteUpDown正在运行"+sTr+"---Up:"+sMe+"已经接到信号");
::Sleep(1000);
srand((int)time(0));//种种子数
iUp=iSpeed-rand();
iDown=iSpeed+rand();
ReleaseSemaphore(ptrUpDownDraw,1,NULL);
ptrUpDownDraw.Unlock();
sTr.Format("%d",iNo);
sMe.Format("%d",iUp);
ptr->SetWindowText("线程WriteUpDown正在运行"+sTr+"---Up:"+sMe);
iNo++;
}
return 0;
}
UINT DrawWindow(LPVOID p)
{
int iNo=1;
CString sTr;
CEdit *ptr=(CEdit *)p;
while(bOnOff)
{
ptrUpDownDraw.Lock();
ptr->SetWindowText("线程DrawWindow正在运行"+sTr+"已经接到信号");
::Sleep(1000);
sTr.Format("%d",iNo);
ptr->SetWindowText("线程DrawWindow正在运行"+sTr);
iNo++;
ReleaseSemaphore(ptrDrawSpd,1,NULL);
ptrDrawSpd.Unlock();
}
return 0;
}
推荐使用第一种方法,第一种方法只声明了句柄,当信号量实例化的时候句柄才指向三个信号量。所以更加支持多态。
程序初始化
程序运行中
分享到:
相关推荐
windowsC++多线程加锁信号量共享内存
小实验二:使用Windows互斥信号量操作函数解决上述线程并发问题,并分析、尝试和讨论线程执行体中有关信号量操作函数调用的正确位置 小实验三:根据同步机制的Peterson软件解决方案尝试自己编程实现线程同步机制和...
c++多线程同步——信号量。非常简单的MFC工程。
这是一个Visual C++信号量线程同步的简单实例工程
用信号量实现线程同步,多个线程共享一个资源。
使用信号量实现线程同步,Visual C++ 6.0 源码文件,信号量对象也属于系统内核对象之一,它包含有使用计数,当使用计数为0时,信号量对象处于无信号状态,当使用计数大于0时,信号量处于有信号状态
利用多线程原理模拟生产与消费的互斥同步过程,使用了信号量
VC线程信号量的使用举例源码,点击启动线程,可发现出现了什么。介绍线程方面的基础知识技巧。
C++线程模板类,锁模板类,使用非常方便,并且支持windows和linux跨平台使用。
在windows平台上建立的c++多线程demo,利用信号量实现线程同步功能。
使用该类可实现C++ 多线程日志的记录,创建了日志记录线程,使用日志等级、队列、信号量、临界区等方法实现记录,可在较高的实时性系统上完成日志记录。
可使用信号量进行进程内的线程之间同步,信号量还可以支持进程间同步。
使用多线程进行串口编程,获取串口数据,利用互斥锁和信号量在不同的线程中安全地操作数据,希望该demo能帮助你快速理解并掌握上述知识。
c++多线程库的使用demo,介绍了互斥库 mutex的使用方式
1、实验目的 在掌握基于消息的windows程序结构和多线程程序设计方法的基础上,设计一个多线程同步的程序。...结合操作系统中信号量与互斥体的概念,在MFC中找到对应的相关类 设计一个多线程同步的程序,
多线程 信号量 线程锁 哲学家 VC MFC SDK HTTPSever 。。。绝对好代码 参考代码 《Windows多线程编程技术与实例》-郝文化-源代码-3316.rar
a: 创建一个线程 b: 创建多个线程 c: 多线程访问同一资源 d: 经典线程同步互斥问题 e: 使用关键段解决子线程互斥问题 f: 利用事件实现线程同步问题 ...I: 信号量 semaphore 解决线程同步问题
通过原子操作、线程同步如互斥锁、读写锁、条件变量、信号量等方法解决C++线程安全问题。同时介绍了线程安全的单例,饿汉模式和懒汉模式。对于C++智能指针作出了简要介绍。同时整理了相关的例子帮助理解。适用人群:...
用C++实现多线程间的同步和互斥,模拟读者、写者问题,支持一个读者一个写者、多个读者一个写者以及多个读者多个写者间的同步和互斥。
摘要:VC/C++源码,系统相关,信号量,线程同步 运行环境:Windows/Delphi7