linux中的线程(线程的创建,销毁)附例程

linux中的线程(线程的创建,销毁)附例程
linux中的线程(线程的创建,销毁)附例程

基于嵌入式Linux多线程聊天系统的设计与实现

基于嵌入式Linux多线程聊天系统的设计与实现 学生姓名王宣达 学号 S2******* 所在系(院)电子信息工程系 专业名称电路与系统年级 2009级 2011年8月3日

中文摘要

外文摘要

目录 1.引言 (1) 2.Linux多线程聊天系统的设计思想 (3) 2.1 聊天系统中服务器的设计思想 (3) 2.2 聊天系统中客户端的设计思想 (3) 3. Linux多线程聊天系统的实现过程 (5) 3.1 多线程聊天系统中服务器端的实现过程 (5) 3.2 多线程聊天系统中客户端的实现过程 (7) 4.Linux多线程系统设计中出现的问题和解决的方法 (12) 4.1 多线程中资源的释放问题 (12) 4.2 (12) 参考文献 (12)

1.引言 在80年代中期,线程技术就应用到了操作系统中,那时在一个进程中只允许有一个线程,这样多线程就意味着多进程,虽然实现了多任务,但是资源消耗还是非常可观的。而到现在,多线程技术已经被许多操作系统所支持,有Windows/NT,还有Linux。 多线程和进程相比有两点优势: 1.它是一种消耗资源非常少的多任务操作方式。在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种消耗非常大的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,这样创建一个线程所占用的空间远远小于创建一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。当然,随着系统的不同,这个差距也不不同。 2.线程间比进程间的通信机制更为便利。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,这时就要用到互斥锁机制来保证线程间的同步。 所以在本文的多线程聊天程序的设计中,采用多线程的方式设计系统更为适宜。其中,系统中用到的操作主要是:线程操作,设置互斥锁。其中,线程操作包括:线程创建,退出,。设置互斥锁包括:创建互斥锁,加锁和解锁。 但是,要实现网络聊天,系统中还要用到linux下的网络编程。 Linux下的网络编程通过socket接口实现。socket 是一种特殊的I/O,可以实现网络上的通信机制。Socket也是一种文件描述符。它具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。常用的Socket

java多线程面试题

java多线程面试题 1.什么是多线程编程?什么时候使用? 多线程一般用于当一个程序需要同时做一个以上的任务。多线程通常用于GUI交互程序。一个新的线程被创建做一些耗时的工作,当主线程保持界面与用户的交互。 2.为什么wait(),notify()和notifyall()函数定义在Object类里面? 因为所有类都是继承于Object类,这样所有类就可以简单的进行多线程编程了。 3.wait()方法和sleep()方法有什么不同? sleep()方法执行后仍然拥有线程,只是延时。而wait方法放弃了线程控制,其它线程可以运行,想要再次运行是要重新开始。 4.Thread和Runnable有什么不同? JA V A线程控制着程序执行的主路径。当你用java命令调用JVM时,JVM创建了一个隐式线程来执行main方法。Thread类提供了主线程调用其它线程并行运行的机制。 Runnable接口定义了一个能被Thread运行的类。实现Runnable的类只需要实行run方法。可以很灵活的扩展现在的已经继承自其它父类的类。而thread则不可以,因为java 只允许继承一个父类。 Runnable可以共享数据,Thread是一个类,而Runnable是一个接口 5.我可以重载start()方法么? 可以重载,重载后还要重载run()方法, 9.编译运行下面的代码会发生什么? 1.public class Bground extends Thread{ 2.public static void main(String argv[]) 3.{ 4. Bground b = new Bground(); 5. b.run(); 6.} 7.public void start()

基于linux的socket多线程通信

1、网络中进程之间如何通信? 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: ?消息传递(管道、FIFO、消息队列) ?同步(互斥量、条件变量、读写锁、文件和写记录 锁、信号量) ?共享内存(匿名的和具名的) ?远程过程调用(Solaris门和Sun RPC) 但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。其实TCP/IP协议族已经帮我们解决了这个问题,网络层的―ip地址‖可以唯一标识网络中的主机,而传输层的―协议+端口‖可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。 使用TCP/IP协议的应用程序通常采用应用编程接口:UNIX BSD的套接字(socket)和UNIX System V的TLI(已经被淘汰),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说―一切皆socket‖。 2、什么是Socket? 上面我们已经知道网络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,而Unix/Linux基本哲学之一就是―一切皆文件‖,都可以用―打开open –> 读写write/read –> 关闭close‖模式来操作。我的理解就是Socket就是该模式的一个实现,socket 即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭),这些函数我们在后面进行介绍。 socket一词的起源 在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的,撰写者为Stephen Carr、Steve Crocker和Vint Cerf。根据美国计算机历史博物馆的记载,Croker写道:―命名空间的元素都可称为套接字接口。一个套接字接口构成一个连接的一端,而一个连接可完全由一对套接字接口规定。‖计算机历史博物馆补充道:―这比BSD的套接字接口定义早了大约12年。‖ 3、socket的基本操作 既然socket是―open—write/read—close‖模式的一种实现,那么socket就提供了这些操作对应的函数接口。下面以TCP为例,介绍几个基本的socket接口函数。 3.1、socket()函数 int socket(int domain, int type, int protocol); socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建一个socket描述符(socket descriptor),它唯一标识一个socket。这个socket描述字跟文件描述字一样,后续的操作都有用到它,把它作为参数,通过它来进行一些读写操作。 正如可以给fopen的传入不同参数值,以打开不同的文件。创建socket的时候,也可以指定不同的参数创建不同的socket描述符,socket 函数的三个参数分别为:

JAVA 面试题总览(书签完整版)

JAVA面试题总览 JAVA基础 1.JAVA中的几种基本数据类型是什么,各自占用多少字节。 2.String类能被继承吗,为什么。 3.String,Stringbuffer,StringBuilder的区别。 4.ArrayList和LinkedList有什么区别。 5.讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数, 字段,当new的时候,他们的执行顺序。 6.用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么, 他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。 7.JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计, 你如何设计。 8.有没有有顺序的Map实现类,如果有,他们是怎么保证有序的。 9.抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接 口么。 10.继承和聚合的区别在哪。 11.IO模型有哪些,讲讲你理解的nio,他和bio,aio的区别是啥,谈谈reactor模型。 12.反射的原理,反射创建类实例的三种方式是什么。 13.反射中,Class.forName和ClassLoader区别。 14.描述动态代理的几种实现方式,分别说出相应的优缺点。 15.动态代理与cglib实现的区别。 16.为什么CGlib方式可以对接口实现代理。 17.final的用途。 18.写出三种单例模式实现。 19.如何在父类中为子类自动完成所有的hashcode和equals实现?这么做有何优劣。 20.请结合OO设计理念,谈谈访问修饰符public、private、protected、default在应 用设计中的作用。 21.深拷贝和浅拷贝区别。 22.数组和链表数据结构描述,各自的时间复杂度。 23.error和exception的区别,CheckedException,RuntimeException的区别。 24.请列出5个运行时异常。 25.在自己的代码中,如果创建一个https://www.360docs.net/doc/16210848.html,ng.String类,这个类是否可以被类加载器加 载?为什么。

实验二-Linux进程、线程及编程

实验二Linux进程、线程及编程实验 一、实验目的 1、通过编写一个完整的守护进程,掌握守护进程编写和调试的方法 2、进一步熟悉如何编写多进程程序 二、实验环境 硬件:PC机一台,JXARM9-2410教学实验平台。 软件:Windows98/XP/2000系统,虚拟机环境下的Linux系统。 三、预备知识 1、fork() fork()函数用于从已存在的进程中创建一个新进程。新进程称为子进程,而原进程称为父进程。使用fork()函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间,包括进程上下文、代码段、进程堆栈、存信息、打开的文件描述符、信号控制设定、进程优先级、进程组号、当前工作目录、根目录、资源限制和控制终端等,而子进程所独有的只有它的进程号、资源使用和计时器等 2、exit()和_exit()的区别 _exit()函数的作用最为简单:直接使进程停止运行,清除其使用的存空间,并销毁其在核中的各种数据结构; exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序。 exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的容写回文件,就是图中的"清理I/O缓冲"一项。 3、wait()和waitpid() wait()函数是用于使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。如果该父进程没有子进程或者他的子进程已经结束,则wait()就会立即返回。 四、实验容 在该实验中,读者首先创建一个子进程1(守护进程),然后在该子进程中新建一个子进程2,该子进程2暂停10s,然后自动退出,并由子进程1收集子线程退出的消息。在这里,子进程1和子进程2的消息都在系统日志文件(例如“/var/log/messages”,日志文件的全路径名因版本的不同可能会有所不同)中输出。在向日志文件写入消息之后,守护进程(子进程1)循环暂停,其间隔时间为10s。 五、实验步骤

多线程常见面试题

1)现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完 后执行? T1.start(); T1.join(); T2.start(); T2.join(); T3.start() 2)11) 为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run() 方法? start()方法最本质的功能是从CPU中申请另一个线程空间来执行run()方法中的代码,它和当前的线程是两条线,在相对独立的线程空间运行 ,也就是说,如果你直接调用线程对象的run()方法,当然也会执行,但那是在当前线程中执行,run()方法执行完成后继续执行下面的代码.而调用start()方法后,run()方法的代码会和当前线程并发(单CPU)或并行(多CPU)执行。 调用线程对象的run方法不会产生一个新的线程 3)在java中wait和sleep方法的不同? sleep()睡眠时,保持对象锁,仍然占有该锁; 而wait()睡眠时,释放对象锁。 sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会; sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。 在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。 wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问; wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。 wiat()必须放在synchronized block中,否则会在program runtime时扔出”https://www.360docs.net/doc/16210848.html,ng.IllegalMonitorStateException“异常。 4)为什么wait, notify 和notifyAll这些方法不在thread类里面? 因为这些是关于锁的 而锁是针对对象的 锁用于线程的同步应用 决定当前对象的锁的方法就应该在对象中吧 我是这么理解的希望对你有帮助

Linux下查看进程和线程

在Linux中查看线程数的三种方法 1、top -H 手册中说:-H : Threads toggle 加上这个选项启动top,top一行显示一个线程。否则,它一行显示一个进程。 2、ps xH 手册中说:H Show threads as if they were processes 这样可以查看所有存在的线程。 3、ps -mp 手册中说:m Show threads after processes 这样可以查看一个进程起的线程数。 查看进程 1. top 命令 top命令查看系统的资源状况 load average表示在过去的一段时间内有多少个进程企图独占CPU zombie 进程:不是异常情况。一个进程从创建到结束在最后那一段时间遍是僵尸。留在内存中等待父进程取的东西便是僵尸。任何程序都有僵尸状态,它占用一点内存资源,仅仅是表象而已不必害怕。如果程序有问题有机会遇见,解决大批量僵尸简单有效的办法是重起。kill是无任何效果的stop模式:与sleep进程应区别,sleep会主动放弃cpu,而stop 是被动放弃cpu ,例单步跟踪,stop(暂停)的进程是无法自己回到运行状态的。 cpu states: nice:让出百分比irq:中断处理占用 idle:空间占用百分比iowait:输入输出等待(如果它很大说明外存有瓶颈,需要升级硬盘(SCSI)) Mem:内存情况 设计思想:把资源省下来不用便是浪费,如添加内存后free值会不变,buff值会增大。判断物理内存够不够,看交换分区的使用状态。 交互命令: [Space]立即刷新显示 [h]显示帮助屏幕

linux进程线程管理实验报告

linux进程线程管理实验报告

————————————————————————————————作者:————————————————————————————————日期:

西安郵電學院 操作系统LINUX实验报告 题目1:进程______ 题目2:线程管理__ 题目3:互斥_____系部名称:计算机学院 专业名称:软件工程 班级:0802 学号:04085048 学生姓名:郭爽乐 时间:2010-10-31

实验一: 进程管理 一.实验目的 通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间等方面的特点, 掌握在POSIX 规范中fork和kill系统调用的功能和使用。 二.实验要求 2.1 实验环境要求 1. 硬件 (1) 主机:Pentium III 以上; (2) 内存:128MB 以上; (3) 显示器:VGA 或更高; (4) 硬盘空间:至少100MB 以上剩余空间。 2. 软件 Linux 操作系统,内核2.4.26 以上,预装有X-Window 、vi、gcc、gdb 和任意web 浏览器。 2.2 实验前的准备工作 学习man 命令的用法,通过它查看fork 和kill 系统调用的在线帮助,并阅读参 考资料,学会fork 与kill 的用法。 复习C 语言的相关内容。 三、实验内容 3.1 补充POSIX 下进程控制的残缺版实验程序 3.2回答下列问题: 1. 你最初认为运行结果会怎么样? 2. 实际的结果什么样?有什么特点?试对产生该现象的原因进行分析。 3. proc_number 这个全局变量在各个子进程里的值相同吗?为什么? 4. kill 命令在程序中使用了几次?每次的作用是什么?执行后的现象是什么? 5. 使用kill 命令可以在进程的外部杀死进程。进程怎样能主动退出?这两种退出方式哪种更好一些? 四、实验结果 4.1 补充完全的源程序 #include #include #include

精选大厂java多线程面试题50题

Java多线程50题 1)什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。 2)线程和进程有什么区别? 线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。更多详细信息请点击这里。 3)如何在Java中实现线程? https://www.360docs.net/doc/16210848.html,ng.Thread类的实例就是一个线程但是它需要调用https://www.360docs.net/doc/16210848.html,ng.Runnable接口来执行,由于线程类本身就是调用的 Runnable接口所以你可以继承https://www.360docs.net/doc/16210848.html,ng.Thread类或者直接调用Runnable接口来重写run()方法实现线程。 4)Thread类中的start()和run()方法有什么区别? 这个问题经常被问到,但还是能从此区分出面试者对Java线程模型的理解程度。start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你

调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。 5)Java中Runnable和Callable有什么不同? Runnable和Callable都代表那些要在不同的线程中执行的任务。Runnable从JDK1.0开始就有了,Callable是在JDK1.5增加的。它们的主要区别是Callable的call()方法可以返回值和抛出异常,而Runnable的run()方法没有这些功能。Callable可以返回装载有计算结果的Future对象。 6)Java内存模型是什么? Java内存模型规定和指引Java程序在不同的内存架构、CPU 和操作系统间有确定性地行为。它在多线程的情况下尤其重要。 Java内存模型对一个线程所做的变动能被其它线程可见提供了保证,它们之间是先行发生关系。 ●线程内的代码能够按先后顺序执行,这被称为程序次序 规则。 ●对于同一个锁,一个解锁操作一定要发生在时间上后发 生的另一个锁定操作之前,也叫做管程锁定规则。 ●前一个对Volatile的写操作在后一个volatile的读操作之 前,也叫volatile变量规则。 ●一个线程内的任何操作必需在这个线程的start()调用之 后,也叫作线程启动规则。 ●一个线程的所有操作都会在线程终止之前,线程终止规

操作系统实验报告(包括线程,进程,文件系统管理,linux+shell简单命令)

操作系统实验报告 班级:030613 学号:03061331 姓名:裴帅帅

实验一:进程的建立 一、实验内容 创建进程及子进程,在父子进程间实现进程通信,创建进程并显示标识等进 程控制块的属性信息,显示父子进程的通信信息和相应的应答信息。 使用匿名管道实现父子进程之间的通信。 二、源程序 1、创建匿名管道 SECURITY_ATTRIBUTES sa; sa.bInheritHandle=true; sa.lpSecurityDescriptor=NULL; sa.nLength=sizeof(SECURITY_ATTRIBUTES); if(!CreatePipe(&m_hRead,&m_hWrite,&sa,0)) { MessageBox("创建匿名管道失败"); return false; } 2、创建子进程 STARTUPINFO si; ZeroMemory(&si,sizeof(STARTUPINFO)); si.cb=sizeof(STARTUPINFO); si.dwFlags=STARTF_USESTDHANDLES; si.hStdInput=m_hRead; si.hStdOutput=m_hWrite; si.hStdError=GetStdHandle(STD_ERROR_HANDLE); if(!CreateProcess(NULL,"子 进.exe",NULL,NULL,true,0,NULL,NULL,&si,&pi)) { MessageBox("创建子进程失败"); CloseHandle(m_hRead); CloseHandle(m_hWrite); m_hRead=NULL; m_hWrite=NULL; return; } 3、销毁子进程 if(m_hRead) CloseHandle(m_hRead);

2019最新Java面试题,常见面试题及答案汇总

ava最新常见面试题+ 答案汇总 1、面试题模块汇总 面试题包括以下十九个模块:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM 。如下图所示: 可能对于初学者不需要后面的框架和JVM 模块的知识,读者朋友们可根据自己的情况,选择对应的模块进行阅读。 适宜阅读人群 需要面试的初/中/高级java 程序员 想要查漏补缺的人 想要不断完善和扩充自己java 技术栈的人 java 面试官 具体面试题 下面一起来看208 道面试题,具体的内容。 一、Java 基础 1.JDK 和JRE 有什么区别? 2.== 和equals 的区别是什么? 3.两个对象的hashCode()相同,则equals()也一定为true,对吗? 4.final 在java 中有什么作用? 5.java 中的Math.round(-1.5) 等于多少? 6.String 属于基础的数据类型吗? 7.java 中操作字符串都有哪些类?它们之间有什么区别? 8.String str="i"与String str=new String(“i”)一样吗? 9.如何将字符串反转? 10.String 类的常用方法都有那些? 11.抽象类必须要有抽象方法吗? 12.普通类和抽象类有哪些区别? 13.抽象类能使用final 修饰吗?

14.接口和抽象类有什么区别? 15.java 中IO 流分为几种? 16.BIO、NIO、AIO 有什么区别? 17.Files的常用方法都有哪些? 二、容器 18.java 容器都有哪些? 19.Collection 和Collections 有什么区别? 20.List、Set、Map 之间的区别是什么? 21.HashMap 和Hashtable 有什么区别? 22.如何决定使用HashMap 还是TreeMap? 23.说一下HashMap 的实现原理? 24.说一下HashSet 的实现原理? 25.ArrayList 和LinkedList 的区别是什么? 26.如何实现数组和List 之间的转换? 27.ArrayList 和Vector 的区别是什么? 28.Array 和ArrayList 有何区别? 29.在Queue 中poll()和remove()有什么区别? 30.哪些集合类是线程安全的? 31.迭代器Iterator 是什么? 32.Iterator 怎么使用?有什么特点? 33.Iterator 和ListIterator 有什么区别? 34.怎么确保一个集合不能被修改?

15个Java多线程面试题及答案

15个Java多线程面试题及答案 1)现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行? 这个线程问题通常会在第一轮或电话面试阶段被问到,目的是检测你对”join”方法是否熟悉。这个多线程问题比较简单,可以用join方法实现。 2)在Java中Lock接口比synchronized块的优势是什么?你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它? lock接口在多线程和并发编程中最大的优势是它们为读和写分别提 供了锁,它能满足你写像ConcurrentHashMap这样的高性能数据结构和有条件的阻塞。Java线程面试的问题越来越会根据面试者的回答来提问。芯学苑老师强烈建议在你在面试之前认真读一下Locks,因为当前其大量用于构建电子交易终统的客户端缓存和交易连接空间。 3)在java中wait和sleep方法的不同?

通常会在电话面试中经常被问到的Java线程面试问题。最大的不同是在等待时wait会释放锁,而sleep一直持有锁。Wait通常被用于线程间交互,sleep通常被用于暂停执行。 4)用Java实现阻塞队列。 这是一个相对艰难的多线程面试问题,它能达到很多的目的。第一,它可以检测侯选者是否能实际的用Java线程写程序;第二,可以检测侯选者对并发场景的理解,并且你可以根据这个问很多问题。如果他用wait()和notify()方法来实现阻塞队列,你可以要求他用最新的Java 5中的并发类来再写一次。 5)用Java写代码来解决生产者——消费者问题。 与上面的问题很类似,但这个问题更经典,有些时候面试都会问下面的问题。在Java中怎么解决生产者——消费者问题,当然有很多解决方法,我已经分享了一种用阻塞队列实现的方法。有些时候他们甚至会问怎么实现哲学家进餐问题。 6)用Java编程一个会导致死锁的程序,你将怎么解决?

Linux 线程实现机制分析

Linux 线程实现机制分析 杨沙洲 国防科技大学计算机学院 2003 年 5 月 19 日 自从多线程编程的概念出现在 Linux 中以来,Linux 多线应用的发展总是与两个问题脱不开干系:兼容性、 效率。本文从线程模型入手,通过分析目前 Linux 平台上最流行的 LinuxThreads 线程库的实现及其不足,描述了 Linux 社区是如何看待和解决兼容性和效率这两个问题的。 一 .基础知识:线程和进程 按照教科书上的定义,进程是资源管理的最小单位,线程是程序执行的最小单位。在操作系统设计上,从进程演化出线程,最主要的目的就是更好的支持 SMP 以及减小(进程/线程)上下文切换开销。 无论按照怎样的分法,一个进程至少需要一个线程作为它的指令执行体,进程管理着资源(比如cpu 、内存、 文件等等),而将线程分配到某个cpu 上执行。一个进程当然可以拥有多个线程,此时,如果进程运行在SMP 机器上,它就可以同时使用多个cpu 来执行各个线程,达到最大程度的并行,以提高效率;同时,即使是在单cpu 的机器上,采用多线程模型来设计程序,正如当年采用多进程模型代替单进程模型一样,使设计更简 洁、功能更完备,程序的执行效率也更高,例如采用多个线程响应多个输入,而此时多线程模型所实现的功能实际上也可以用多进程模型来实现,而与后者相比,线程的上下文切换开销就比进程要小多了,从语义上 来说,同时响应多个输入这样的功能,实际上就是共享了除cpu 以外的所有资源的。 针对线程模型的两大意义,分别开发出了核心级线程和用户级线程两种线程模型,分类的标准主要是线程的调度者在核内还是在核外。前者更利于并发使用多处理器的资源,而后者则更多考虑的是上下文切换开销。在目前的商用系统中,通常都将两者结合起来使用,既提供核心线程以满足smp 系统的需要,也支持用线程 库的方式在用户态实现另一套线程机制,此时一个核心线程同时成为多个用户态线程的调度者。正如很多技 术一样,"混合"通常都能带来更高的效率,但同时也带来更大的实现难度,出于"简单"的设计思路,Linux 从 一开始就没有实现混合模型的计划,但它在实现上采用了另一种思路的"混合"。 在线程机制的具体实现上,可以在操作系统内核上实现线程,也可以在核外实现,后者显然要求核内至少实现了进程,而前者则一般要求在核内同时也支持进程。核心级线程模型显然要求前者的支持,而用户级线程模型则不一定基于后者实现。这种差异,正如前所述,是两种分类方式的标准不同带来的。 当核内既支持进程也支持线程时,就可以实现线程-进程的"多对多"模型,即一个进程的某个线程由核内调度,而同时它也可以作为用户级线程池的调度者,选择合适的用户级线程在其空间中运行。这就是前面提到的"混合"线程模型,既可满足多处理机系统的需要,也可以最大限度的减小调度开销。绝大多数商业操作系统(如Digital Unix 、Solaris 、Irix )都采用的这种能够完全实现POSIX1003.1c 标准的线程模型。在核外实现的线程又可以分为"一对一"、"多对一"两种模型,前者用一个核心进程(也许是轻量进程)对应一个线程,将线程调度等同于进程调度,交给核心完成,而后者则完全在核外实现多线程,调度也在用户态完成。后者就是前面提到的单纯的用户级线程模型的实现方式,显然,这种核外的线程调度器实际上只需要完成线程运行栈的切换,调度开销非常小,但同时因为核心信号(无论是同步的还是异步的)都是以进程为单位的,因而无法定位到线程,所以这种实现方式不能用于多处理器系统,而这个需求正变得越来 内容: 一.基础知识:线程和进程 二.Linux 2.4内核中的轻量进程实现 三.LinuxThread 的线程机制 四.其他的线程实现机制 参考资料 关于作者 对本文的评价 订阅: developerWorks 时事通讯

linux进程间通讯

linux进程间通讯 管道(FIFO): 管道可分为命名管道和非命名管道(匿名管道),匿名管道只能用于父、子进程间通讯,命名管道可用于非父子进程。命名管道就是FIFO,管道是先进先出的通讯方式。 消息队列: 消息队列用于2个进程间通讯,首先在1个进程中创建1个消息队列,然后可向消息队列中写数据,而另一进程可从该消息队列中读取数据。 注意,消息队列是以创建文件的方式建立的,若1个进程向某消息队列中写入数据后,另一进程并未读取这些数据,则即使向消息队列中写数据的进程已退出,但保存在消息队列中的数据并未消失,也就是说下次再从这个消息队列中读数据时,还是会读出已退出进程所写入的数据。 信号量: linux中的信号量类似于windows中的信号量。 共享内存: 共享内存,类似于windows中dll的共享变量,但linux下的共享内存区不需要象DLL这样的东西,只要先创建1个共享内存区,其它进程按照一定步骤就能访问到这个共享内存区中的数据(可读可写)。 信号——signal 套接字——socket 各种ipc机制比较: 1.匿名管道:速度较慢,容量有限,且只有父、子进程间能通讯; 2.命名管道(FIFO):任何进程间都能通讯,但速度较慢; 3.消息队列:容量受系统限制,且要对读出的消息进行测试(读出的是新写入的消息,还是以前写入的, 尚未被读取的消息); 4.信号量:不能传递复杂信息,只能用来同步; 5.共享内存:容量大小可控,速度快,但共享内存区不包含同步保护,对共享内存区的访问需由用户实 现同步保护。 另外,共享内存同样可用于线程间通讯,不过没必要,线程间本来就已共享了同一进程内的一块内存。 线程间同步方法: 1.临界区:使多线程间串行访问公共资源或1段代码,速度较快,适合控制数据访问; 2.互斥量:为同步对共享资源的单独访问而设计的; 3.信号量:为控制1个具有有限数量用户资源而设计; 4.事件对象:用来通知线程有一些事件已发生,从而启动后继任务。

多线程与并发面试题

多线程与并发面试题

JAVA多线程和并发基础面试问答 原文链接译文连接作者:Pankaj 译者:郑旭东校对:方腾飞 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,可是你依然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:非常赞同这个观点) Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它能够被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的单一进程。线程能够被称为轻量级进程。线程需要较少的资源来创立和驻留在进程中,而且能够共享进程中的资源。 2. 多线程编程的好处是什么?

在多线程程序中,多个线程被并发的执行以提高程序的效率,CPU不会因为某个线程需要等待资源而进入空闲状态。多个线程共享堆内存(heap memory),因此创立多个线程去执行一些任务会比创立多个进程更好。举个例子,Servlets比CGI更好,是因为Servlets支持多线程而CGI不支持。 3. 用户线程和守护线程有什么区别? 当我们在Java程序中创立一个线程,它就被称为用户线程。一个守护线程是在后台执行而且不会阻止JVM终止的线程。当没有用户线程在运行的时候,JVM关闭程序而且退出。一个守护线程创立的子线程依然是守护线程。 4. 我们如何创立一个线程? 有两种创立线程的方法:一是实现Runnable接口,然后将它传递给Thread的构造函数,创立一个Thread对象;二是直接继承Thread类。若想了解更多能够阅读这篇关于如何在Java中创立线程的文章。 5. 有哪些不同的线程生命周期?

操作系统实验报告理解Linux下进程和线程的创建并发执行过程。

操作系统上机实验报告 实验名称: 进程和线程 实验目的: 理解unix/Linux下进程和线程的创建、并发执行过程。 实验内容: 1.进程的创建 2.多线程应用 实验步骤及分析: 一、进程的创建 下面这个C程序展示了UNIX系统中父进程创建子进程及各自分开活动的情况。 fork( ) 创建一个新进程。 系统调用格式: pid=fork( ) 参数定义: int fork( ) fork( )返回值意义如下: 0:在子进程中,pid变量保存的fork( )返回值为0,表示当前进程是子进程。 >0:在父进程中,pid变量保存的fork( )返回值为子进程的id值(进程唯一标识符)。 -1:创建失败。 如果fork( )调用成功,它向父进程返回子进程的PID,并向子进程返回0,即fork( )被调用了一次,但返回了两次。此时OS在内存中建立一个新进程,所建的新进程是调用fork( )父进程(parent process)的副本,称为子进程(child process)。子进程继承了父进程的许多特性,并具有与父进程完全相同的用户级上下文。父进程与子进程并发执行。 2、参考程序代码 /*process.c*/ #include #include main(int argc,char *argv[]) { int pid; /* fork another process */ pid = fork(); if (pid < 0) { /* error occurred */ fprintf(stderr, "Fork Failed"); exit(-1);

线程编程方面笔试题

线程编程方面java笔试题 60、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 答:有两种实现方法,分别是继承Thread类与实现Runnable接口 用synchronized关键字修饰同步方法 反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。 61、sleep() 和 wait() 有什么区别? 答:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 62、同步和异步有何异同,在什么情况下分别使用他们?举例说明。 答:如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。 当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。 63、启动一个线程是用run()还是start()? 答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。 64、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 答:不能,一个对象的一个synchronized方法只能由一个线程访问。 65、请说出你所知道的线程同步的方法。 答:wait():使一个线程处于等待状态,并且释放所持有的对象的lock。 sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉Interrupt edException异常。 notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。 Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。 66、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么? 答:多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 同步的实现方面有两种,分别是synchronized,wait与notify

Linux进程同步

Linux进程同步 1.概述 Linux系统同一时间可能有多个进程在执行,因此需要一些同步机制来同步各个进程对于共享资源的访问。在Linux内核中有相应的同步技术实现,包括原子操作、信号量、读写信号量、自旋锁和等待队列等等。本文从同步的机制出发,重点研究讨论了Linux系统非阻塞的同步机制、Linux系统内核同步机制、Linux系统多线程的同步机制。 我们在实际生活中经常碰到这样的一类问题:有时候我们在使用打印机实现某种功能的时候,有可能使多个任务的打印结果交织在一起,造成混乱。这时多任务之间的同步操作便显得非常重要。比如在工业控制中的多个相互合作的任务,可以将数据采集、数据处理和数据输出划分为不同的任务。在它们之间建立一种必要的通信机制,使得采集任务可以通知数据处理任务。在新采集的数据已经处理完毕的时候,数据处理任务可以及时的通知输出任务,告诉输出任务需要实现的结果已经经过计算完成,需要通过输出设备输出。多任务的引入主要有以下有点:多任务的引入改善了系统的资源利用率,并且提高了系统的吞吐量,尤其是在嵌入式多任务操作系统中,但是与此同时多任务的引入也带来了另外的问题,那就是多个任务间如何协调、合作共同完成一个大的系统功能。特别是当我们在竞争使用临界资源,或是需要相互通知某些事件发生时。 另外在Linux操作系统里,在某一个时间段里,有些资源可能被很多内核同时来调用,这时我们便需要一套同步机制来同步各内核执行单元对共享数据的访问。尤其是在多核通信的机制上更需要同步机制来协调进程之间的通信。在Linux内核中有相应的技术实现,主要包括原子操作、信号量、读写信号量、自旋锁和等待队列。利用常用的同步机制可以有效地实现多任务、多内核之间的优化,实现其之间的合理调度。 2.同步机制 2.1临界资源与临界区 我们把在一段时间内只允许一个任务访问的资源叫做临界资源。这里与vxworks中的信号量的使用比较的类似。任务在占有CPU之后,还需要相应的资源才可以正常的执行。如果此时任务需要的资源被其它任务所占有,那么当前任务必须等待前一个任务完成并释放该资源后,才可以执行。把程序中使用临界资源的代码称为临界区。如果此刻临界资源未能访问,该任务便可以进入临界区,并将其设置为被访问状态。然后,即可以对临界资源进行操作。待任务完成后释放其占用的资源。

相关文档
最新文档