浅谈linux多线程编程和windows多线程编程的异同

上传人:l**** 文档编号:134583398 上传时间:2020-06-06 格式:DOC 页数:10 大小:130.50KB
返回 下载 相关 举报
浅谈linux多线程编程和windows多线程编程的异同_第1页
第1页 / 共10页
浅谈linux多线程编程和windows多线程编程的异同_第2页
第2页 / 共10页
浅谈linux多线程编程和windows多线程编程的异同_第3页
第3页 / 共10页
浅谈linux多线程编程和windows多线程编程的异同_第4页
第4页 / 共10页
浅谈linux多线程编程和windows多线程编程的异同_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《浅谈linux多线程编程和windows多线程编程的异同》由会员分享,可在线阅读,更多相关《浅谈linux多线程编程和windows多线程编程的异同(10页珍藏版)》请在金锄头文库上搜索。

1、浅谈 linux 多线程编程和 windows 多线程编程的异同很早以前就想写写linux下多线程编程和windows下的多线程编程了,但是每当写时又不知道从哪个地方写起,怎样把自己知道的东西都写出来,下面我就谈谈linux多线程及线程同步,并将它和windows的多线程进行比较,看看他们之间有什么相同点和不同的地方。其实最开始我是搞windows下编程的,包括windows编程,windows 驱动,包括usb驱动,ndis驱动,pci驱动,1394驱动等等,同时也一条龙服务,做windows下的应用程序开发,后面慢慢的我又对linux开发产生比较深的兴趣和爱好,就转到搞linux开发了。在

2、接下来的我还会写一些博客,主要是写linux编程和windows编程的区别吧,现在想写的是linux下usb驱动和windows下usb驱动开发的区别,这些都是后话,等我将linux多线程和windows多线程讲解完后,我再写一篇usb驱动,谈谈windows 和linux usb驱动的东东。好了,言归正传。开始将多线程了。首先我们讲讲为什么要采用多线程编程,其实并不是所有的程序都必须采用多线程,有些时候采用多线程,性能还没有单线程好。所以我们要搞清楚,什么时候采用多线程。采用多线程的好处如下:(1)因为多线程彼此之间采用相同的地址空间,共享大部分的数据,这样和多进程相比,代价比较节俭,因为多

3、进程的话,启动新的进程必须分配给它独立的地址空间,这样需要数据表来维护代码段,数据段和堆栈段等等。(2)多线程和多进程相比,一个明显的优点就是线程之间的通信了,对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。但是对于多线程就不一样了。他们之间可以直接共享数据,比如最简单的方式就是共享全局变量。但是共享全部变量也要注意哦,呵呵,必须注意同步,不然后果你知道的。呵呵。(3)在多cpu的情况下,不同的线程可以运行不同的cpu下,这样就完全并行了。反正我觉得在这种情况下,采用多线程比较理想。比如说你要做一个任务分2个步骤,你为提高工作效率

4、,你可以多线程技术,开辟2个线程,第一个线程就做第一步的工作,第2个线程就做第2步的工作。但是你这个时候要注意同步了。因为只有第一步做完才能做第2步的工作。这时,我们可以采用同步技术进行线程之间的通信。针对这种情况,我们首先讲讲多线程之间的通信,在windows平台下,多线程之间通信采用的方法主要有:(1)共享全局变量,这种方法是最容易想到的,呵呵,那就首先讲讲吧,比如说吧,上面的问题,第一步要向第2步传递收据,我们可以之间共享全局变量,让两个线程之间传递数据,这时主要考虑的就是同步了,因为你后面的线程在对数据进行操作的时候,你第一个线程又改变了数据的容,你不同步保护,后果很严重的。你也知道,

5、这种情况就是读脏数据了。在这种情况下,我们最容易想到的同步方法就是设置一个bool flag了,比如说在第2个线程还没有用完数据前,第一个线程不能写入。有时在2个线程所需的时间不相同的时候,怎样达到最大效率的同步,就比较麻烦了。咱们可以多开几个缓冲区进行操作。就像生产者消费者一样了。如果是2个线程一直在跑的,由于时间不一致,缓冲区迟早会溢出的。在这种情况下就要考虑了,是不让数据写入还是让数据覆盖掉老的数据,这时候就要具体问题具体分析了。就此打住,呵呵。就是用bool变量控制同步,linux 和windows是一样的。既然讲道了这里,就再讲讲其它同步的方法。同样 针对上面的这个问题,共享全局变量

6、同步问题。除了采用bool变量外,最容易想到的方法就是互斥量了。呵呵,也就是传说中的加锁了。windows下加锁和linux下加锁是类似的。采用互斥量进行同步,要想进入那段代码,就先必须获得互斥量。linux上互斥量的函数是:windows下互斥量的函数有:createmutex 创建一个互斥量,然后就是获得互斥量waitforsingleobject函数,用完了就释放互斥量ReleaseMutex(hMutex),当减到0的时候 核会才会释放其对象。下面是windows下与互斥的几个函数原型。HANDLE WINAPI CreateMutex(_in LPSECURITY_ATTRIBUTE

7、S lpMutexAttributes,_in BOOL bInitialOwner,_in LPCTSTR lpName);可以可用来创建一个有名或无名的互斥量对象第一参数 可以指向一个结构体SECURITY_ATTRIBUTES一般可以设为null;第二参数 指当时的函数是不是感应感应状态 FALSE为当前拥有者不会创建互斥第三参数 指明是否是有名的互斥对象 如果是无名 用null就好。DWORD WINAPI WaitForSingleObject(_in HANDLE hHandle,_in DWORD dwMilliseconds);第一个是 创建的互斥对象的句柄。第二个是 表示将在

8、多少时间之后返回 如果设为宏INFINITE 则不会返回 直到用户自己定义返回。对于linux操作系统,互斥也是类似的,只是函数不同罢了。在linux下,和互斥相关的几个函数也要闪亮登场了。pthread_mutex_init函数:初始化一个互斥锁;pthread_mutex_destroy函数:注销一个互斥锁;pthread_mutex_lock函数:加锁,如果不成功,阻塞等待;pthread_mutex_unlock函数:解锁;pthread_mutex_trylock函数:测试加锁,如果不成功就立即返回,错误码为EBUSY;至于这些函数的用法,google上一搜,就出来了,呵呵,在这里不

9、多讲了。windows下还有一个可以用来保护数据的方法,也是线程同步的方式就是临界区了。临界区和互斥类似。它们之间的区别是,临界区速度快,但是它只能用来同步同一个进程的多个线程。临界区的获取和释放函数如下:EnterCriticalSection() 进入临界区; LeaveCriticalSection()离开临界区。 对于多线程共享存的东东就讲到这里了。(2)采用消息机制进行多线程通信和同步,windows下面的的消息机制的函数用的多的就是postmessage了。Linux下的消息机制,我用的较少,就不在这里说了,如果谁熟悉的,也告诉我,呵呵。(3)windows下的另外一种线程通信方法

10、就是事件和信号量了。同样针对我开始举得例子,2个线程同步,他们之间传递信息,可以采用事件(Event)或信号量(Semaphore),比如第一个线程完成生产的数据后,就必须告诉第2个线程,他已经把数据准备好了,你可以来取走了。第2个线程就把数据取走。呵呵,这里可以采用消息机制,当第一个线程准备好数据后,就直接postmessage给第2个线程,按理说采用postmessage一个线程就可以搞定这个问题了。呵呵,不是重点,省略不讲了。对于linux,也有类似的方法,就是条件变量了,呵呵,这里windows和linux就有不同了。要特别讲讲才行。对于windows,采用事件和信号量同步时候,都会使

11、用waitforsingleobject进行等待的,这个函数的第一个参数是一个句柄,在这里可以是Event句柄,或Semaphore句柄,第2个参数就是等待的延迟,最终等多久,单位是ms,如果这个参数为INFINITE,那么就是无限等待了。释放信号量的函数为ReleaseSemaphore();释放事件的函数为SetEvent。当然使用这些东西都要初始化的。这里就不讲了。Msdn一搜,神马都出来了,呵呵。神马都是浮云!对于linux操作系统,是采用条件变量来实现类似的功能的。Linux的条件变量一般都是和互斥锁一起使用的,主要的函数有:pthread_mutex_lock ,pthread_m

12、utex_unlock,pthread_cond_initpthread_cond_signalpthread_cond_waitpthread_cond_timewait为了和windows操作系统进行对比,我用以下表格进行比较:对照以上表格,总结如下:(1) Pthread_cleanup_push,Pthread_cleanup_pop:这一对函数push和pop的作用是当出现异常退出时,做一些清除操作,即当在push和pop函数之间异常退出,包括调用pthread_exit退出,都会执行push里面的清除函数,如果有多个push,注意是是栈,先执行后面的那个函数,在执行前面的函数,但是

13、注意当在这2个函数之间通过return 退出的话,执不执行push后的函数就看pop函数中的参数是不是为0了。还有当没有异常退出时,等同于在这里面return退出的情况,即:当pop函数参数不为0时,执行清除操作,当pop函数参数为0时,不执行push函数中的清除函数。(2)linux的pthread_cond_signal和SetEvent的不同点Pthread_cond_singal释放信号后,当没有Pthread_cond_wait,信号马上复位了,这点和SetEvent不同,SetEvent是不会复位的。详解如下:条件变量的置位和复位有2种常用模型:第一种模型是当条件变量置位时(sig

14、naled)以后,如果当前没有线程在等待,其状态会保持为置位(signaled),直到有等待的线程进入被触发,其状态才会变为unsignaled,这种模型以采用Windows平台上的Auto-set Event 为代表。第2种模型则是Linux平台的pthread所采用的模型,当条件变量置位(signaled)以后,即使当前没有任何线程在等待,其状态也会恢复为复位(unsignaled)状态。条件变量在Linux平台上的这种模型很难说好坏,在实际应用中,我们可以对代码稍加改进就可以避免这种差异的发生。由于这种差异只会发生在触发没有被线程等待在条件变量的时刻,因此我们只需要掌握好触发的时机即可。

15、最简单的做法是增加一个计数器记录等待线程的个数,在决定触发条件变量前检查该变量即可。示例 使用 pthread_cond_wait() 和 pthread_cond_signal()pthread_mutex_t count_lock;pthread_cond_t count_nonzero;unsigned count;decrement_count()pthread_mutex_lock(&count_lock);while (count = 0)pthread_cond_wait(&count_nonzero, &count_lock);count = count - 1;pthread

16、_mutex_unlock(&count_lock);increment_count()pthread_mutex_lock(&count_lock);if (count = 0)pthread_cond_signal(&count_nonzero);count = count + 1;pthread_mutex_unlock(&count_lock);(3) 注意Pthread_cond_wait条件返回时互斥锁的解锁问题extern int pthread_cond_wait _P (pthread_cond_t *_cond,pthread_mutex_t *_mutex); 调用这个函数时,线程解开mutex指向的锁并

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作范文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号