Windows多线程总结(3)-- 线程同步(使用互斥对象实现线程同步)

原创 2015年11月27日 18:44:07

         上一篇说明了多线程是存在着问题的,起始就是多线程操作同一数据而不同步的问题。那么如果实现线程的同步呢?

         线程的同步有多种实现方式:

        互斥内核对象、事件内核对象、可等待的计数器内核对象、信号量内核对象和等待函数等等来实现线程的同步。

        我们先用互斥内核对象实现线程同步。

      

         互斥内核对象,能够确保线程拥有对单个资源的互斥访问权,互斥对象包含一个使用数量,一个线程ID和一个计数器。其中ID用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。

使用CreateMutext函数,创建或打开一个互斥对象,然后利用互斥对象完成线程间的同步。

HANDLE CreateMutex(
     LPSECURITY_ATTRIBUTESl  pMutexAttributes, // 指向安全属性的指针
     BOOL  bInitialOwner, // 初始化互斥对象的所有者
     LPCTSTR  lpName // 指向互斥对象名的指针
);
参数 类型及说明
lpMutexAttributes :

         可以使用NULL,表示使用默认的安全性。
bInitialOwner
:

          表示互斥对象的初始拥有者。如果为真,创建这个互斥对象的线程获得该对象的所有权,否则,该线程不获得该互斥对象的所有权。
lpName
:

          指定互斥体对象的名字。如果为NULL,则创建一个匿名的互斥对象。


       当结束后,使用ReleaseMutex函数进行释放指定对象的所有权。

BOOL WIANPI ReleaseMutex(
    HANDLE hMutex
);

      需要注意,线程只有主动请求共享对象的所有权才有可能获取到该所有权,我们可以通过WaitForSingleObject来实现

DWORD WaitForSingleObject(
     HANDLE hHandle,
     DWORD dwMilliseconds
);
         hHandle为句柄,此处为 hMutex的句柄,

        dwMilliseconds为指定时间间隔,单位为毫秒。如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。如果dwMilliseconds为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。

       WaitForSingleObject函数用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。

   

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <windows.h>

int tickets = 100;
HANDLE hMutex;
int idx = 0;

DWORD  WINAPI ThreadProc1(LPVOID lpThreadParameter)
{

	while (TRUE)
	{
		WaitForSingleObject(hMutex, INFINITE);
		if (tickets>0)
		{
			Sleep(1);
			printf("thread1 ----  %d \n", tickets--);
		}
		else
		{
			break;
		}

		ReleaseMutex(hMutex);
	}
	return 0;
}


DWORD  WINAPI ThreadProc2(LPVOID lpThreadParameter)
{

	while (TRUE)
	{
	 	WaitForSingleObject(hMutex, INFINITE);
		if (tickets > 0)
		{
			Sleep(1);
			printf("thread2 ----  %d \n", tickets--);
		}
		else
		{
			break;
		}
		ReleaseMutex(hMutex);

	}
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
 
	//创建线程
	HANDLE  h1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	HANDLE  h2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);

	CloseHandle(h1);
	CloseHandle(h2);


	//创建互斥对象
	hMutex = CreateMutex(NULL, FALSE, NULL);
	/*<pre name="code" class="html">        hMutex = CreateMutex(NULL, TRUE, NULL);  //如果第二个参数设置为true 那么此时互斥对象为主线程所有  
ReleaseMutex(hMutex); //当第二参数的为True的时候 则需要使用该函数 进行释放互斥对象 只有释放后线程1和线程2才能获取 */system("pause");return 0;}


Windows 互斥对象在线程同步上的运用

互斥对象在线程同步时的使用 1 多线程在资源共享的时候出现的问题          在程序中如果不同线程对同一个对象进行操作的话就有可能出现因为线程切换而导致的问题。例如下面的程序 #inc...
  • zhuhuangtianzi
  • zhuhuangtianzi
  • 2014年08月25日 22:26
  • 1744

【Linux多线程】同步与互斥的区别

很多人把同步与互斥这两个概念混淆,这里说一下它们的区别。一、同步与互斥的区别1. 同步同步,又称直接制约关系,是指多个线程(或进程)为了合作完成任务,必须严格按照规定的 某种先后次序来运行。例如,线程...
  • lisong694767315
  • lisong694767315
  • 2015年04月29日 23:11
  • 6454

【Java】线程并发、互斥与同步

网络上对于线程的解析总是天花龙凤的,给你灌输一大堆概念,考研、本科的操作系统必修课尤甚,让你就算仔细看完一大堆文章都不知道干什么。 下面不取网站复制粘贴,在讲解自己的Java线程并发、互斥与同步之前先...
  • yongh701
  • yongh701
  • 2015年01月17日 09:22
  • 2502

JAVA多线程机制之同步与互斥

一个多线程的程序,两个或者多个线程可能需要访问同一个数据资源。这时就必须考虑数据安全的问题,需要线程互斥或者同步。线程的互斥当多个线程需要访问同一资源时,要求在一个时间段内只能允许一个线程来操作共享资...
  • jianggujin
  • jianggujin
  • 2016年01月04日 20:12
  • 3449

Windows 互斥对象在线程同步上的运用

互斥对象在线程同步时的使用 1 多线程在资源共享的时候出现的问题          在程序中如果不同线程对同一个对象进行操作的话就有可能出现因为线程切换而导致的问题。例如下面的程序 #inc...
  • zhuhuangtianzi
  • zhuhuangtianzi
  • 2014年08月25日 22:26
  • 1744

多线程同步互斥实例——使用synchronized实现线程通信和互斥

线程互斥概念       线程互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。 实现线程同步互斥的四种方式 ...
  • lu930124
  • lu930124
  • 2016年04月25日 15:58
  • 3917

线程同步与互斥:互斥锁

为什么需要互斥锁? 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印...
  • lianghe_work
  • lianghe_work
  • 2015年08月18日 09:59
  • 9052

linux多线程编程——同步与互斥

我们在前面文章中已经分析了多线程VS多进程,也分析了线程的使用,现在我们来讲解一下linux多线程编程之同步与互斥。 现在,我们不管究竟是多线程好还是多进程好,先讲解一下,为什么要使用多线程? 一、 ...
  • zqixiao_09
  • zqixiao_09
  • 2015年12月15日 17:18
  • 1661

秒杀多线程第七篇 经典线程同步 互斥量Mutex

阅读本篇之前推荐阅读以下姊妹篇: 《秒杀多线程第四篇一个经典的多线程同步问题》 《秒杀多线程第五篇经典线程同步关键段CS》 《秒杀多线程第六篇经典线程同步事件Event》   前面介绍了关键...
  • lien0906
  • lien0906
  • 2015年04月15日 16:08
  • 1570

<MFC笔记> 四种线程同步(或互斥)方式小结

一,什么是线程同步? 同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。这里的同步千万不要理解成那个同时进行,应是指协同、协助、互相配合。 线程同步是指多线程通过特定的设置(如互斥量,...
  • EbowTang
  • EbowTang
  • 2014年06月10日 21:35
  • 2000
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Windows多线程总结(3)-- 线程同步(使用互斥对象实现线程同步)
举报原因:
原因补充:

(最多只允许输入30个字)