随笔分类 - C/C++
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 多线程创建其实十分简单,在windows系统下面有很多函数可以创建多线程,比如说_beginthread。我们就可以利用它为我们编写一段简单的多线程代码,[cpp] view plaincopy#include<windows.h>#include<process.h>#include<stdio.h>unsignedintvalue=0;voidprint(void*argv){while(1){printf("&value=%x,va
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 相信有过多线程编程经验的朋友,都吃过死锁的苦。除非你不使用多线程,否则死锁的可能性会一直存在。为什么会出现死锁呢?我想原因主要有下面几个方面: (1)个人使用锁的经验差异 (2)模块使用锁的差异 (3)版本之间的差异 (4)分支之间的差异 (5)修改代码和重构代码带来的差异 不管什么原因,死锁的危机都是存在的。那么,通常出现的死锁都有哪些呢?我们可以一个一个看过来, (1)忘记释放锁[cpp] view plaincopyvoiddata_process(){EnterCr...
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在多线程存在的环境中,除了堆栈中的临时数据之外,所有的数据都是共享的。如果我们需要线程之间正确地运行,那么务必需要保证公共数据的执行和计算是正确 的。简单一点说,就是保证数据在执行的时候必须是互斥的。否则,如果两个或者多个线程在同一时刻对数据进行了操作,那么后果是不可想象的。 也许有的朋友会说,不光数据需要保护,代码也需要保护。提出这个观点的朋友只看到了数据访问互斥的表象。在程序的运行空间里面,什么最重要的呢?代码吗?当然不是。代码只是为了数据的访问存在的。数据才是我们一切工作的出发点和落脚
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在windows系统中,系统本身为我们提供了很多锁。通过这些锁的使用,一方面可以加强我们对锁的认识,另外一方面可以提高代码的性能和健壮性。常用的锁以下四种:临界区,互斥量,信号量,event。 (1)临界区 临界区是最简单的一种锁。基本的临界区操作有,[cpp] view plaincopyInitializeCriticalSectionEnterCriticalSectionLeaveCriticalSectionDeleteCriticalSection 如果想要对数据进行互斥...
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 自旋锁是SMP中经常使用到的一个锁。所谓的smp,就是对称多处理器的意思。在工业用的pcb板上面,特别是服务器上面,一个pcb板有多个cpu是 很正常的事情。这些cpu相互之间是独立运行的,每一个cpu均有自己的调度队列。然而,这些cpu在内存空间上是共享的。举个例子说,假设有一个数据 value = 10,那么这个数据可以被所有的cpu访问。这就是共享内存的本质意义。 我们可以看一段Linux 下的的自旋锁代码(kernel 2.6.23,asm-i386/spinlock.h),就可..
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 原子锁是多线程编程中的一个特色。然而,在平时的软件编写中,原子锁的使用并不是很多。这其中原因很多,我想主要有两个方面。第一,关于原子锁这方面的 内容介绍的比较少;第二,人们在编程上面习惯于已有的方案,如果没有特别的需求,不过贸然修改已存在的代码。毕竟对很多人来说,不求有功,但求无过。保持 当前代码的稳定性还是很重要的。 其实,早在《多线程数据互斥》这篇博客中,我们就已经介绍过原子锁。本篇博客主要讨论的就是原子锁怎么使用。中间的一些用法只是我个人的一些经验,希望能够抛砖引玉,多听听大家...
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 编写程序不容易,编写多线程的程序更不容易。相信编写过多线程的程序都应该有这样的一个痛苦过程,什么样的情况呢?朋友们应该看一下代码就明白了,[cpp] view plaincopyvoiddata_process(){EnterCriticalSection();if(/*errorhappens*/){LeaveCriticalSection();return;}if(/*othererrorhappens*/){return;}LeaveCriticalSection();} 上面的代码说
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 嵌套锁这个概念,主要是为了根据编程中的一种情形引申出来的。什么情况呢,我们可以具体说明一下。假设你在处理一个公共函数的时候,因为中间涉及公共数 据,所以你加了一个锁。但是,有一点比较悲哀。这个公共函数自身也加了一个锁,而且和你加的锁是一样的。所以,除非你的使用的是信号量,要不然你的程序一 辈子也获取不了这个锁。[cpp] view plaincopyHANDLEhLock;voidsub_func(){/*...*/WaitForSingleObject(hLock,INFINITE);d.
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在编写多线程的时候,有一种情况是十分常见的。那就是,有些公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。通常而言,在读的过程中, 往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地降低我们程序的效率。那么有没有一种方法,可以专门处理这种多读少写的情况呢? 有,那就是读写锁。 (1)首先,我们定义一下基本的数据结构。[cpp] view plaincopytypedefstruct_RWLock{intcount;intstate;HANDLEhRead;HA...
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 生产者-消费者是很有意思的一种算法。它的存在主要是两个目的,第一就是满足生产者对资源的不断创造;第二就是满足消费者对资源的不断索取。当然,因为空间是有限的,所以资源既不能无限存储,也不能无限索取。 生产者的算法,[cpp] view plaincopyWaitForSingleObject(hEmpty,INFINITE);WaitForSingleObject(hMutex,INIFINITE);/*producenewresources*/ReleaseMutex(hMutex);...
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 预防死锁的注意事项:(1)在编写多线程程序之前,首先编写正确的程序,然后再移植到多线程(2)时刻检查自己写的程序有没有在跳出时忘记释放锁(3)如果自己的模块可能重复使用一个锁,建议使用嵌套锁(4)对于某些锁代码,不要临时重新编写,建议使用库里面的锁,或者自己曾经编写的锁(5)如果某项业务需要获取多个锁,必须保证锁的按某种顺序获取,否则必定死锁(6)编写简单的测试用例,验证有没有死锁(7)编写验证死锁的程序,从源头避免死锁 首先,定义基本的数据结构和宏,[cpp] view plaincopy
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 对于编写多线程的朋友来说,队列具有天生的互斥性。在队列里面,一个负责添加数据,一个负责处理数据。谁也不妨碍谁,谁也离不开谁。所以,队列具有天生的并行性。[cpp] view plaincopy#defineMAX_NUMBER1000L#defineSTATUSint#defineOK0#defineFALSE-1typedefstruct_QUEUE_DATA{intdata[MAX_NUMBER];inthead;inttail;}QUEUE_DATA; 此时,一个线程压入数据,操作为p
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 软件调试是我们软件开发过程中的重要一课。在前面,我们也讨论过程序调试,比如说这里。今天,我们还可以就软件调试多讲一些内容。比如说条件断点,数据断点,多线程断点等等。[cpp] view plaincopy#include<stdio.h>intvalue=0;voidtest(){inttotal;intindex;total=0;for(index=0;index<100;index++)total+=index*index;value=total;return;}int
        阅读全文
            
摘要:【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在互斥数据访问中有一种多读少写的情况。正对这么一种情形,我们也提出了读写锁的方案。但是呢,这个锁有些缺陷。什么缺陷呢?那就是,这个写锁需要在所有的读锁完成之后才能写。否则的话,写锁需要这么一直等下去。 那么,有没有什么办法能使得写操作快速一点进行呢?那就是顺序锁。[cpp] view plaincopytypedefstruct_SEQUENCE_LOCK{unsignedintsequence;HANDLEhLock;}SEQUENCE_LOCK; 有了这么一个数据结构之后。那么读锁怎么.
        阅读全文
            
摘要:http://blog.csdn.net/feixiaoxing/article/details/7055128【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 前面,为了使得写操作快速进行,我们定义了顺序锁。但是顺序锁有个缺点,那就是处理的数据不能是指针,否则可能会导致exception。那么有没有办法使得处理的数据包括指针呢?当然要是这个链表没有锁,那就更好了。 针对这种无锁链表,我们可以初步分析一下,应该怎么设计呢? (1)读操作没有锁,那么怎么判断读操作正在进行呢,只能靠标志位了; (2)写操作没有锁,那么读操作只能一个线...
        阅读全文
            
摘要:http://blog.csdn.net/feixiaoxing/article/details/7058393【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 要想编写多线程,那就要使用锁。而在软件编写中,数据结构是少不了的。所以,我们在编写多线程的时候,就需要考虑一下如何在数据结构中插入锁。当然,有些数据结构是没有锁的,所以自然这个锁并不一定是必须的。 比如说,我们编写一个多线程堆栈,应该怎么做呢,[cpp] view plaincopytypedefstruct_STACK{void*pData;intmaxLen;inttop...
        阅读全文
            
摘要:http://blog.csdn.net/feixiaoxing/article/details/7060751【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 多核编程并不是最近才兴起的新鲜事物。早在intel发布双核cpu之前,多核编程已经在业内存在了,只不过那时候是多处理器编程而已。为了实现多核编 程,人们开发实现了几种多核编程的标准。open-mp就是其中的一种。对于open-mp还不太熟悉的朋友,可以参照维基百科的相关解释。 open-mp的格式非常简单,原理也不难。它的基本原理就是创建多个线程,操作系统把这几个线程分到几个核..
        阅读全文
            
摘要:http://blog.csdn.net/feixiaoxing/article/details/7064559【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 多线程一直是我比较喜欢的话题,当然也是很多朋友比较害怕的话题。喜欢它,因为它确实可以提高pc的使用效率;讨厌它,因为如果对它处理不好,反而会导致更大的麻烦。这里断断续续写了这么多,没有什么新意,主要是想结合自己这么多年的个人经历谈一谈自己的想法而已。真心希望这些文章能够达到抛砖引玉的效果,更多的达人可以奉献出自己的经验和方法。谢谢。 (01)多线程的哪些儿事(优先级反转) (...
        阅读全文
            
摘要:http://blog.csdn.net/feixiaoxing/article/details/7061582【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 优先级反转对于编写应用层的人员来说不大会发生,但是对于操作系统的设计者来说确是一个逃不过去的问题。要知道怎么样处理优先级反转?那么先看看它是怎么发生的。 (1)调度队列和线程优先级 在操作系统中,线程的状态有很多种。比如说,线程的状态可能是suspend、block、ready、die几种类型。我们把所有的ready线程放在一个队列里面,这就构成了一个基本的调度队列。 ...
        阅读全文
            
摘要:http://tech.it168.com/a2010/1116/1126/000001126683.shtml【IT168专稿】说起VC,有人想到维生素C(维C),有人想到风险投资(venture capital), 程序员们尤其是做底层开发的程序员或老程序员们第一感觉肯定会想到Visual C++6.0。为什么是6.0而不是其它的版本?这里的原因就不用我再多讲了,因为太经典了!这个经典已经有了10年的光荣历史,微软的Visual Studio系列也已经发展到了Visual Studio 2010。漫长的辉煌中Visual C++6.0也暴露出了一些问题,在这篇文章中我们将从Visual C
        阅读全文
            
 
                     
                    
                 
                    
                
 
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号