`
ribishuangba
  • 浏览: 291445 次
文章分类
社区版块
存档分类
最新评论

十二多线程

 
阅读更多
<meta content="text/html; charset=utf-8" http-equiv="CONTENT-TYPE"> <meta content="OpenOffice.org 2.2 (Linux)" name="GENERATOR"> <meta content="freebird" name="AUTHOR"> <meta content="20070510;9550000" name="CREATED"> <meta content="root" name="CHANGEDBY"> <meta content="20070717;14010300" name="CHANGED"> <style type="text/css"> <!-- @page { size: 8.5in 11in; margin: 0.79in } P { margin-bottom: 0.08in; line-height: 0.1in } H1 { margin-top: 0.24in; margin-bottom: 0.23in; line-height: 200%; page-break-inside: avoid } H1.western { font-family: "Liberation Serif", serif; font-size: 22pt } H1.cjk { font-family: "DejaVu Sans"; font-size: 22pt } H1.ctl { font-family: "DejaVu Sans"; font-size: 22pt } H2 { margin-top: 0.18in; margin-bottom: 0.18in; line-height: 173%; page-break-inside: avoid } H2.western { font-family: "Cambria", serif; font-size: 16pt } H2.cjk { font-family: "宋体", "SimSun"; font-size: 16pt } H2.ctl { font-family: "Times New Roman", serif; font-size: 16pt } --> </style>

多线程

信号驱动I/0和异步I/0的区别

信号驱动I/0是指进程预先告知内核,使得当某个描述字上发生某事时,内核使用信号通知相关进程。

异步I/0是进程执行I/0系统调用(比如读或者写),内核启动I/0操作后立刻返回进程,进程可以在I/0操作执行期间继续处理别的事情,然后当I/0操作成功或者失败时,内核以进程预先设定的方式通知进程。

使用锁保护同步数据的原则

多个线程使用同一个数据,必须保护该数据;

如果多个线程共用一个基础类型变量,应该声明为volatile,防止编译器使用将其缓存到寄存器内的优化方式;

共享的整数变量应该优先使用原子操作来修改其值;

有时候,可以考虑将某些需要共享的数据只让一个单独线程处理,然后将该线程作为一种服务提供给其他线程使用;

如果有很多数据需要在线程间共享,可以考虑使用数据库来管理这些数据。

不确定的情况下,使用锁来保护。

Readers/Writers锁

假设有很多线程共享一个变量,只有一个(或者很少的)线程负责修改这个变量的值,其他(或者大多数的)线程只是读取变量的值。如果采用常规思路,所有线程访问该变量都必须获得一个锁,这样的效率是很低的。因为如果写变量的线程没有执行对该变量的修改操作时,其他的读线程理论上都可以安全的读该变量的值。常规思路的解决方案让所有的读线程都排队,所以我们需要readers/writers锁来提供更好的效率。

在readers/writers锁的解决方案里,只要没有任何线程在修改共享变量的值,所有其他线程都可以读取该变量的值,如果有一个线程正在修改共享变量的值,其他任何线程无论读取还是改写的操作都必须等待获得锁。这种解决方案适用于在写操作较少,读操作较多的多线程环境中。

readers/writers锁有两种策略,读优先或者写优先策略。读优先策略是指总是让读操作先完成,写优先是指只要有正在执行的或者等待的写操作,读操作就需要等待写操作完成以后才能执行。图书馆书籍查找系统通常使用读操作,而航班预定系统由于强调数据的有效性,采用写优先策略。

ACE提供了跨平台的两个类ACE_RW_Thread_Mutex和ACE_RW_Process_Mutex。

前者提供了线程间的同步,后者提供了进程范围的同步。这两个类采用了写优先策略。ACE的readers/writer锁仅适用于读操作较多而写操作较少的多线程环境,注意在大多数其他情况下,readers/writers锁都比采用mutex的常规思路慢。


信号量

(摘自http://blog.yesky.com/134/polaris0161/1555634.shtml)

信号量是一种Linux的资源,它可以让不同的进程间进行相互通信,因此它也被看作是IPC集中的一员。信号量的作用是在两个或多个进程访问公共资源集时 保持同步。

信号量是一个计数器的值,它可以被几个进程作为一个集合以原子的方式执行。信号量的计数器控制着对资源的访问控制,信号量提供了两个主要的操作来处理计数器的值:

(1)资源的使用者在使用资源之前等待信号量。如果信号量的值为0,则继续等待,如果大于0,则将信号量值减1,使用者开始使用资源。

(2)资源的使用者在资源使用完毕后通知信号量。使用者通知信号量不再使用资源了,信号量的值加1,检查等待信号量的使用者的序列,以确定是否有其他的使用者在等待之中。

使用信号量进行进程间的通信一般牵涉到以下操作:

相关信号量的操作函数一般应该包含下面的头文件;

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

1.创建信号量:在程序使用信号量之前,必须首先创建信号量。创建信号量的函数原形如下所示:

int semget(key_t key,int nsems,int semflg);

参数说明:

(1)key:在本地系统中表示要创建或者访问的信号量集的关键字,当然为了避免与其他的信号量产生冲突,我们可以简单的利用IPC_PRIVATE来表示一个新建的信号量。

(2)nsems:要创建或者要访问的信号量集中信号量的数目。

(3)指定不同的选项和权限位的标志。可以为IPC_CREATE,IPC_EXCL.

创建一个新的信号量:

int semid;

semid=semget(0x1234,2,IPC_CREATE|IPC_EXCL|0600);

if(semid<0)

{

process error case.

}else

{

do the next thing;

}

使用已经存在的信号量:

int semid;

semid=semget(0x1234,0,0);

if(semid<0)

{}else

{}

2.初始化信号集:

int semctl(int semid,int semnum,int cmd,union semun arg);

union semun

{

int val;

struct semid_ds *buf;

ushort *array;

};

eg:

int semid;

int z;

union semun arg;

ushort initv[]={4,2};

arg.array=initv;

z=semctl(semid,2,SETALL,arg);

3.等待通知信号量:等待信号量和通知信号量都是利用函数semop(),只是相关的参数不同而已。

int semop(int semid,struct sembuf *sops,unsigned nsops);

struct sembuf

{

short sem_num; /*信号量的索引*/

short sem_op; /*信号量的相关操作为一个整数(正数表示通知信号量,负数表示等待信号量)*/

short sem_flg;/*相关的操作标记*/

};

eg:

int z;

static struct sembuf sops[]=

{

{1,-1,0},

{0,-1,0}

};

z=semop(semid,sops,2);

如果是通知信号量,则sembuf的值可以设为

static struct sembuf sops[]=

{

{1,+1,0},

{0,+1,0}

};

z=semop(semid,sops,2);

4.删除信号量

当信号量在系统中没有用处后,应该将其删除,这样才能释放内核中的支持表所占用的资源。

int semctl(int semid,int semnum,int cmd,union semun arg);

eg:

int semid;

int z;

union semun arg;

z=semctl(semid,0,IPC_RMID,arg);

值得一提的是信号量的使用遵循自愿的原则的,也就是说信号量并不能强制的限制应用程序对资源的访问,我们在编写每一个程序的时候,都将通过资源的原则来执行如下操作:

1)在访问受控资源前等待信号量。

2)释放受控的资源后要通知信号量。

分享到:
评论

相关推荐

    多线程实验_1

    C#多线程实验,就AutoResetEvent,ManualResetEvent,Thread.join(),委托多线程回调。

    操作系统实训报告进程同步和互斥

    操作系统实训报告进程同步和互斥通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。哲学家有N个,也定全体到达后开始讨论:在讨论的间隙哲学家进餐,每人进餐时都需使用刀、叉各一把,所有哲学家刀...

    JAVA面试必成功之JAVA面试秘籍

    Java多线程,包括多线程基础、synchronized连环问、线程池、AQS、原子类等。Spring,包括Spring基础、bean、IOC、AOP、事务、Spring MVC、Spring Boot等。MySQL,包括MySQL的基础、事务、锁、分库分表、读写分离、...

    邮件客户端(练手项目十二)

    在移动139邮箱测试通过,测试中发现问题,收邮件没有开线程如果邮件特别多的情况下会出现卡着按钮(主线程被阻塞)的情况,需要使用代码的时候注意监听开线程. 难度反而较项目11难度略低,引入JMAIL包,开发,不是...

    与程序、IT有关的一些资料1

    linux下多进程、多线程编程.txt memcache.txt mySQL.txt nlp.txt perl.txt ph,jsp,asp.txt php.txt python.txt sed.txt shell.txt Symbian.txt Visual Basic appliation.txt Visual C++.txt W3C.txt wcf.txt web 2.0...

    Python自学笔记 Python核心编程第二版学习笔记 很详细的学习笔记 建议收藏 共148页.pdf

    目录 一、 解释器options 3 二、 Python基础(chapter3) 12 三、 python对象(chapter4) 19 四、 数字(chapter5) 25 五、 序列: 字符串, 列表和元组(chapter6) 30 ...十七、 多线程编程(chapter18) 147

    Delphi讲义 chm格式

    八、多线程编程 九、分布式多层数据库开发(MIDAS技术和DataSnap) 十、XML及其应用 十一、Internet服务器端Web编程 十二、Internet Express快速网络开发 十三、MIDAS技术在Web上的应用 十四、Web Snap...

    嵌入式系统实验讲义.rar

    实验十二 Linux下多线程应用程序设计 81 实验十三 Linux下按键实验 92 实验十四 电机控制实验 97 实验十五 UDP通讯实验 107 实验十六 基于ARM的多通道仪表数据采集实验 115 实验十七 简单嵌入式WEB服务器实验 ...

    java实验报告.docx

    实验七 Java 多线程程序设计应用 1 实验八 Java 泛型程序设计应用 5 实验九 Java 常用类库的应用 8 实验十 Java 标准输入/输出流的程序设计;文件读/写的程序设计应用 12 实验十一 Java 枚举类型的应用 18 实验十二 ...

    Java se 教学PPT

    此PPT文档讲述了java se部分知识,分十二章,内容包括输入输出系统,多线程,图形用户界面,网络编程,数据库编程,第十二章还简述了WBE应用。

    java实验代码

    实验11 多线程处理  实验12 I/O及文件处理  实验目的:掌握并使用Java中的I/O和文件。  心得体会:对于该实验,由于比较难,只是基本掌握了文件读写的方法和规则,还有待17周JAVA实训时继续攻坚克难。 ...

    JNI完全技术手册 带完整书签

    chap 15:JNI在多线程中的应用... 101 chap 16:JNI限制(多线程)... 105 chap 17:使用 Java Native Interface 的最佳实践... 106 1.性能缺陷... 107 2.正确性缺陷... 117 3.避免常见缺陷... 121 4.结束语.....

    Delphi认证讲义(全)

    Delphi高级编程课程安排一、Delphi程序设计的一般问题二、异常处理三、创建DLL 动态连接库四、创建VCL 组件五、COM 技术六、ActiveX 控件七、数据库开发(ADO、BDE和dbExpress)八、多线程编程九、分布式多层数据库...

    Java基础知识点总结.docx

    十二、 多线程★★★★ 39 为什么要使用多线程 39 创建线程和启动 39 线程的生命周期 44 线程管理 45 线程同步 49 线程通信 52 线程池 58 死锁 64 线程相关类 65 十三、 同步★★★★★ 67 十四、 Lock接口 70 十五...

    Java实验报告配套Java程序设计基础(第3版)实验指导书使用

    本Java实验报告配套Java程序设计基础(第3版)实验指导书使用。主要包括: 实验一 基本数据类型 实验二 结构语句 ...实验十 多线程 实验十一 图形界面设计 实验十二 事件处理 实验十三 绘图程序设计

    JAVA语言程序设计源代码 清华大学版

    实验一 Java开发环境的安装与配置,熟悉Java程序结构 实验二 Java语言基础 实验三 类和对象 实验四 java继承与多态 ...实验九 Java多线程 实验十 输入输出流 实验十一 Java网络编程 实验十二 Java与数据库连接

    软件设计师重点考点

    9.2 Java多线程机制 295 9.3 流式输入输出与文件处理 295 9.3.1 Java输入输出类库继承关系 296 9.3.2基于标准输入输出的IO操作 296 9.3.3文件读写及随机访问 297 9.3.4Java的文件管理 297 9.4 Java网络通信 297 ...

    2018年C++教程网的linux网络编程视频共41集百度云下载链接.rar

    处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline...

    《Java网络开发》课程实验教学手册

    自行设计一个多线程程序,用继承Thread类或实现Runnable接口两种方法来实现。 (1)编程求1!+2!+3!+…+n!(n&gt;=1); 注意:n的值运行时通过键盘输入,使用BufferedReader类读取n的值 (2)编程实现将一个文件的内容写到...

Global site tag (gtag.js) - Google Analytics