讲_线程进程安全.pptx

上传人:茅**** 文档编号:90315892 上传时间:2023-05-14 格式:PPTX 页数:46 大小:385.61KB
返回 下载 相关 举报
讲_线程进程安全.pptx_第1页
第1页 / 共46页
讲_线程进程安全.pptx_第2页
第2页 / 共46页
点击查看更多>>
资源描述

《讲_线程进程安全.pptx》由会员分享,可在线阅读,更多相关《讲_线程进程安全.pptx(46页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第三章第三章线程线程/进程平安进程平安进程和线程是两个范围不同的概念。进程是程序在计算机上的一次执行活动。运行一个程序,相当于启动了一个进程。进程是操作系统进行资源分配的单位,通俗地讲,是一个正在执行的程序。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创立和撤消另一个线程,同一进程中的多个线程之间可以并发执行。比方,一个在线播放软件,在播放歌曲的同时还可以进行下载,就可认为这两件工作由不同的线程完成。线程和进程的开发和相关操作,在程序设计中具有重要地位,线程和进程的平安和系统的平安息息相关。对于不够熟练的程序员来说

2、,很容易出现平安隐患,而这些平安问题又具有不间断发生,难于调试等特点。一般说来,线程的平安性主要来源于其运行的并发性和对资源的共享性;进程的平安性主要在应用级别,在于其对系统的威胁性,不过对于系统软件的开发者,进程平安的考虑需要更加深入。本章主要针对线程和进程开发过程中的平安问题进行讲述,首先基于面向对象语言,讲解线程的的基本机制,然后讲解线程操作过程中的几个重要的平安问题:线程同步平安、线程协作平安、线程死锁、线程控制,最后讲解进程平安。3.1 线程机制3.1.1 为什么需要线程由于Java 在线程操作方面具有较好的面向对象特性,也具有一定的代表性本章基于Java 语言进行讲解。实际上,多线

3、程最直观的说法是:让应用程序看起来好似同时能做好几件事情。为了表达这个问题,我们用一个案例来说明。比方,需要在控制台上每隔1 秒钟打印一个欢送信息。代码如下所示:public class P03_01 public static void main(String args)while(true)System.out.println(Wel e);try Thread.sleep(1000);catch(Exception ex)System.out.println(其他工作);/代码行1 该程序似乎没有什么问题,运行时,Wel e 也能不断打印。但是,我们发现,打印函数中的while 循环是个

4、死循环,也就是说,这个死循环不运行完毕,程序将不能作其他事情。比方,程序中的代码行1 永远也无法运行。这就给程序的功能形成了巨大的阻碍。在实际应用开发的过程中,经常会出现一个程序看起来同时作好几件事情的情况,如 程序进行一个用时较长的计算,希望该计算进行的时候,程序还可以做其他事情;程序进行一个用时较长的计算,希望该计算进行的时候,程序还可以做其他事情;软件要能够接受多个客户的请求,而让客户感觉不出等待;媒体播放器在播放歌曲的同时也能下载电影;财务软件在后台进行财务汇总的同时还能接受终端的请求;等等。在这些情况下,多线程就能够起到巨大的作用。线程和进程的关系很紧密,进程和线程是两个不同的概念,

5、但是进程的范围大于线程。通俗地说,进程就是一个程序,线程是这个程序能够同时做的各件事情。比方,媒体播放机运行时就是一个进程,而媒体播放机同时做的下载文件和播放歌曲,就是两个线程。以上代码如果用线程来进行开发,在Java 语言里面,就可以用如P03_02.java 的方式(其他语言类似)。运行,就会发现,此时“打印欢送信息和“其他工作就“同时做了。3.1.2 线程机制和生命周期每个程序至少自动拥有一个线程,称为主线程。当程序加载到内存时,启动主线程。从上节的程序可以看出,代码行:实际上相当于实例化一个新的线程对象,并运行该线程中的run()函数。该线程的运行并不影响主线程向下执行,这是为什么呢?

6、这是由于多线程的机制实际上相当于CPU 交替分配给不同的代码段来运行:也就是说,某一个时间片,某线程运行,下一个时间片,另一个线程运行,各个线程都有抢占CPU 的权利,至于决定哪个线程抢占,是操作系统需要考虑的事情。由于时间片的轮转非常快,用户感觉不出各个线程抢占CPU 的过程,看起来好似计算机在“同时做好几件事情。Wel eThread wt=new Wel eThread();wt.start();一个线程有从创立、运行到消亡的过程,称为线程的生命周期。用线程的状态state 说明线程处在生命周期的哪个阶段。线程有创立、可运行、运行中、阻塞、死亡五种状态。通过线程的控制与调度可使线程在这几

7、种状态间转化。这五种状态详细描述如下:1:创立状态:使用new 运算符创立一个线程后。该线程仅仅是一个空对象,系统没有分配资源。2:可运行状态:使用start()方法启动一个线程后,系统分配了资源,使该线程处于可运行状态Runnable。3:运行中状态:占有CPU,执行线程的run()方法。4:阻塞状态:运行的线程因某种原因停止继续运行。5:死亡状态:线程结束。线程的平安隐患可能出现在各个状态。一般说来,线程的平安性来源于两个方面:1:多个线程之间可能会共享进程的内存资源。2:CPU 的某个时间片分配给哪个线程使用,默认情况下无法由用户控制。多线程的平安问题比较复杂,解决方法繁多,在这里我们阐

8、述几个比较典型的平安问题。3.2 线程同步平安3.2.1 线程同步默认情况下,线程都是独立的,而且异步执行,线程中包含了运行时所需要的数据或方法,而不需要外部的资源或方法,也不必关心其它线程的状态或行为。但是在多个线程在运行时共享数据的情况下,就需考虑其他线程的状态和行为,否则就不能保证程序的运行结果的正确性。在某些工程中,经常会出现线程同步的问题,即:多个线程在访问同一资源时,会出现平安问题。本节基于一个简单的案例,针对线程的同步问题进行阐述。所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法。通俗地讲,一个线程是否能够抢占CPU,必须考虑

9、另一个线程中的某种条件,而不能随便让操作系统按照默认方式分配CPU,如果条件不具备,就应该等待另一个线程运行,直到条件具备。3.2.2 案例分析给出一个案例:有假设干张飞机票,2 个线程去卖它们,要求没有票时能够提示:没有票了。以最后剩下3 张票为例。首先用传统方法来编写这段代码。代码如P03_03.java 所示。运行,控制台打印如下:这段程序貌似没有问题。但是它是很不平安的,并且这种不平安性很难发现,会给工程后期维护带来巨大的代价。观察程序中的代码行1 处的注释,当只剩下一张票时,线程1 卖出了最后一张票,接着要运行ticketNum-,但在ticketNum-还没来得及运行的时候,线程2

10、 有可能抢占CPU,来判断当前有无票可卖,此时,由于线程1 还没有将ticketNum-,当然票数还是1,线程2 判断还可以买票,这样,最后一张票卖出了两次。当然,上面的程序中,没有给线程2 以买票的时机,实际上票都由线程1 卖出,我们看不出其中的问题。为了让大家看清这个问题,我们模拟线程1 和线程2 交替卖票的情况。将P03_03.java 的代码改为P03_04.java:该代码中,增加了一行:程序休眠1000 毫秒,让另一个线程来抢占CPU。运行,控制台打印如下:最后一张票被卖出两次,系统不可靠。更为严重的是,该问题的出现很具有随机性。比方,有些工程在实验室运行阶段没有问题,因为哪个线程

11、抢占CPU,是由操作系统决定的,用户并没有权利干预,也无法预测,所以,工程可能在商业运行阶段出现了问题,等到维护人员去查问题的时候,由于问题出现的随机性,问题可能就不出现了。这种工作往往给维护带来了巨大的代价。以上案例是多个线程消费有限资源的情况,该情况下还有很多其他案例,如:多个线程,向有限空间写数据时:线程1 写完数据,空间满了,但没来得及告诉系统;此时另一个线程抢占CPU,也来写,不知道空间已满,造成溢出。3.2.3 解决方案怎样解决这个问题?很简单,就是让一个线程卖票时其他线程不能抢占CPU。根据定义,实际上相当于要实现线程的同步,通俗地讲,可以给共享资源在本例中为票加一把锁,这把锁只

12、有一把钥匙。哪个线程获取了这把钥匙,才有权利访问该共享资源。有一种比较直观的方法,可以在共享资源如“票每一个对象内部都增加一个新成员,标识“票是否正在被卖中,其他线程访问时,必须检查这个标识,如果这个标识确定票正在被卖中,线程不能抢占CPU。这种设计理论上当然也是可行,但由于线程同步的情况并不是很普遍,仅仅为了这种小概率事件,在所有对象内部都开辟另一个成员空间,带来极大的空间浪费,增加了编程难度,所以,一般不采用这种方法。现代的编程语言的设计思路都是把同步标识加在代码段上,确切的说,是把同步标识放在“访问共享资源如卖票的代码段上。不同语言中,同步代码段的实现模型类似,只是表达方式有些不同。这里

13、以Java 语言为例,在Java 语言中,synchronized 关键字可以解决这个问题,整个语法形式表现为:注意,synchronized 后的“同步锁对象,必须是可以被各个线程共享的,如this、某个全局标量等。不能是一个局部变量。其原理为:当某一线程运行同步代码段时,在“同步锁对象上置一标记,运行完这段代码,标记消除。其他线程要想抢占CPU 运行这段代码,必须在“同步锁对象上先检查该标记,只有标记处于消除状态,才能抢占CPU。在上面的例子中,this 是一个“同步锁对象。synchronized(同步锁对象)/访问共享资源,需要同步的代码段 因此,在上面的案例中,可以将将卖票的代码用s

14、ynchronized 代码块包围起来,“同步锁对象取this。如代码P03_05.java 所示。运行,可以得到如下效果。这说明程序运行完全正常。从以上代码可以看出,该方法的本质是将需要独占CPU 的代码用synchronized(this)包围起来。如前所述,一个线程进入这段代码之后,就在this 上加了一个标记,直到该线程将这段代码运行完毕,才释放这个标记。如果其他线程想要抢占CPU,先要检查this 上是否有这个标记。假设有,就必须等待。但是可以看出,该代码实际上运行较慢,因为一个线程的运行,必须等待另一个线程将同步代码段运行完毕。因此,从性能上讲,线程同步是非常消耗资源的一种操作。我

15、们要尽量控制线程同步的代码段范围,理论上说,同步的代码段范围越小,段数越少越好,因此在某些情况下,推荐将小的同步代码段合并为大的同步代码段。实际上,在Java 内,还可以直接把synchronized 关键字直接加在函数的定义上,这也是一种可以推荐的方法。不过,值得一提的是,如果不能确定整个函数都需要同步,那就要尽量防止直接把synchronized 加在函数定义上的做法。如前所述,要控制同步粒度,同步的代码段越小越好,synchronized 控制的范围越小越好,否则造成不必要的系统开销。所以,在实际开发的过程中,要十分小心,因为过多的线程等待可能造成系统性能的下降,甚至造成死锁。3.3 线

16、程协作平安3.3.1 线程协作有些情况下,多个线程合作完成一件事情的几个步骤,此时线程之间实现了协作。如一个工作需要假设干个步骤,各个步骤都比较耗时,不能因为它们的运行,影响程序的运行效果,最好的方法就是将各步用线程实现。但是,由于线程随时都有可能抢占CPU,可能在前面一个步骤没有完成时,后面的步骤线程就已经运行,该平安隐患造成系统得不到正确结果。3.3.2 案例分析给出一个案例:线程1 负责完成一个复杂运算比较耗时,线程2 负责得到结果,并将结果进行下一步处理。如:某个科学计算系统中,线程1 负责计算1-1000 各个数字的和(暂且认为它非常耗时),线程2负责得到这个结果并且写入数据库。读者

17、首先想到的是将耗时的计算放入线程。这是正确的想法。首先用传统线程方法来编写这段代码,代码如P03_06.java 所示。该程序貌似没有问题,也能够打印正确结果,但是和上一节的例子一样,它也是很不平安的,这种不平安性也很难发现,也会给工程后期维护带来巨大的代价。该程序的平安隐患在哪里呢?观察cal()函数中的代码,当线程th1 运行后,线程th2 运行,此时,线程th2 随时可能抢占CPU,而不一定要等线程th1 运行完毕。当然,在上面的例子中,可能因为线程th1 运行较快,th2 在它运行的过程中没有抢占CPU,“碰巧得到了正确结果,但是如果让线程th2 抢占CPU,这样,系统可能得不到正确结

18、果。为了解释这个问题,将P03_06.java 的代码改为P03_07.java该代码中,增加了一行:程序休眠1 毫秒,让另一个线程来抢占CPU。运行,控制台打印如下:很显然,这个结果不是我们所需要的。那为什么sum 得到的结果为1 呢?很明显,线程th1 的start函数运行时,相当于让求和过程以多线程形式运行,在它“休眠之际,th2 就抢占了CPU,在求和还没开始做或只完成一局部时就打印sum,导致得到不正常结果。3.3.3 解决方案怎样解决?显而易见,方法是:在运行一个线程时,命令其他线程等待该线程运行完毕,才能抢占CPU 进行运行。对于该问题,不同语言解决方法类似。以Java 语言为例

19、,在Java 语言中,线程的join()方法可以解决这个问题。见代码P03_08.java运行正常。实际上,该程序相当于摒弃了“线程就是为了程序看起来同时做好几件事情的思想,将并发程序又变成了顺序的,如果线程th1没有运行完毕的话,程序会在th.join()处堵塞。如果cal()函数耗时较长,程序将一直等待。一般的方法是,可以将该工作放在另一个线程中,这样,既不会堵塞主程序,又能够保证数据平安性。见代码P03_09.java 3.4 线程死锁平安3.4.1 线程死锁死锁(DeadLock),是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象。此时称系统处于死锁状态,这些

20、永远在互相等待的线程称为死锁线程。产生死锁的四个必要条件是:互斥条件:资源每次只能被一个线程使用。如前面的“线程同步代码段,就是只能被一个线程使用的典型资源;请求与保持条件:一个线程请求资源,但因为某种原因,该资源无法分配给它,于是该线程阻塞,此时,它对已获得的资源保持不放;不剥夺条件:进程已获得的资源,在未使用完之前,不管其是否阻塞,无法强行剥夺;循环等待条件:假设干进程之间互相等待,形成一种头尾相接的循环等待资源关系。这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。3.4.2 案例分析以Java 语言为例,死锁一般来源于代码段的同步

21、,当一段同步代码被某线程运行时,其他线程可能进入堵塞状态(无法抢占CPU),而刚好在该线程中,访问了某个对象,此时,除非同步锁定被解除,否则其他线程就不能访问那个对象。这可以称为“线程正在等待一个对象资源。如果出现一种极端情况,一个线程等候另一个对象,而另一个对象又在等候下一个对象,以此类推。这个“等候链如果进入封闭状态,也就是说,最后那个对象等候的是第一个对象,此时,所有线程都会陷入无休止的相互等待状态,造成死锁。尽管这种情况并非经常出现,但一旦碰到,程序的调试将变得异常艰难。在这里给出一个死锁的案例,如代码P03_10.java 这段程序也貌似没有问题。但是和上一节的例子一样,它也是很不平

22、安的,这种不平安性也很难发现。观察run()函数中的代码,当th1 运行后,进入代码段1,锁定了S1,如果此时th2 运行,抢占CPU,进入代码段3,锁定S2,那么th1 就无法运行代码段2,但是又没有释放S1,此时,th2 也就不能运行代码段4。造成互相等待。为了模拟这个过程,我们在程序中增加让其休眠的代码,好让另一个线程来抢占CPU。将P03_10.java 的代码改为P03_11.java该代码中,增加了一行:程序休眠1000 毫秒,让另一个线程来抢占CPU。运行,控制台打印如下:两个线程陷入无休止的等待。其原因是,线程th1进入代码段1 后,线程2 抢占CPU,锁定了S2,而线程th1

23、对S1 的锁定又没有解除,造成线程th2无法运行下去,当然,由于线程th2锁定了S2,线程th1也无法运行下去。死锁是一个很重要的问题,它能导致整个应用程序慢慢终止,尤其是当开发人员不熟悉如何分析死锁环境的时候,还很难被别离和修复。3.4.3 解决方案就语言本身来说,尚未直接提供防止死锁的帮助措施,需要我们通过谨慎的设计来防止。一般情况下,我们主要是针对死锁产生的四个必要条件来进行破坏,用以防止和预防死锁。在系统设计、线程开发等方面,注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,防止线程永久占据系统资源。以Java 为例,Java 并不提供对死锁的检测机制。但可以通过java t

24、hread dump来进行判断:一般情况下,当死锁发生时,Java 虚拟机处于挂起状态,thread dump 可以给出静态稳定的信息,从操作系统上观察,虚拟机的CPU 占用率为零,这时可以收集thread dump,查找waiting for monitor entry 的线程,如果大量thread 都在等待给同一个地址上锁,说明很可能死锁发生了。解决死锁没有简单的方法,这是因为线程产生死锁都各有各的原因,而且往往具有很高的负载。从技术上讲,可以用如下方法来进行死锁排除:可以撤消陷于死锁的全部线程。可以逐个撤消陷于死锁的进程,直到死锁不存在。从陷于死锁的线程中逐个强迫放弃所占用的资源,直至死

25、锁消失。提示:关于死锁的检测与解除,有很多重要算法,如资源分配算法、银行家算法等。在操作系统的一些参考资料中应该可以进行足够了解。w 很多软件产品内置了死锁解决策略,可做参考。如:数据库死锁。一个连接占用了另一个连接所需的数据库锁,它可能阻塞另一个连接。如果两个或两个以上的连接相互阻塞,产生死锁。该情况下,一般会强制销毁一个连接通常是使用最少的连接,并回滚其事务。这将释放所有与已经结束的事务相关联的锁,至少允许其他连接中有一个可以获取它们正在被阻塞的锁。资源池耗尽死锁。资源池太小,而每个线程需要的资源超过了池中的可用资源,产生死锁。此时可以增加连接池的大小或者重构代码,以便单个线程不需要同时使

26、用很多资源。3.5 线程控制平安3.5.1 平安隐患w 线程控制主要是对线程生命周期的一些操作,如暂停、继续、消亡等。本节以Java 语言为例,讲解线程控制中的一些平安问题。Java 中提供了对线程生命周期进行控制的函数:stop():停止线程;suspend():暂停线程的运行;resume():继续线程的运行:destroy():让线程销毁;等等。w 线程生命周期中的平安问题主要表达在:线程暂停或者终止时,可能对某些资源的锁并没有释放,它所保持的任何资源都会保持锁定状态;线程暂停之后,我们无法预计它什么时候会继续(一般和用户操作有关),如果对某个资源的锁长期被保持,其他线程在任何时候都无法

27、再次访问该资源,极有可能造成死锁。w 针对这个问题,为减少出现死锁的可能,Java 1.2 中,将Thread 的stop(),suspend(),resume()以及destroy()方法定义为“已过时方法,不再推荐使用。3.5.2 案例分析如前所述,线程的暂停和继续,早期采用suspend()和resume()方法,但是容易发生死锁。以线程暂停为例,调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被“挂起的线程恢复运行。如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。下面给出一个案例,来说明

28、这个问题。屏幕上不断打印欢送信息,点击按钮,打印工作暂停;再点击,继续打印。传统代码如P03_12.java 如果点击“暂停按钮,则暂停打印;再点击,继续打印。如上所述,该代码实际上在事件响应中用suspend()和resume()来控制线程的暂停和继续,是不平安的。3.5.3 解决方案解决该问题,常见的方法有如下几种:1:当需要暂停时,干脆让线程的run()方法结束运行以释放资源(实际上就是让该线程永久结束);继续时,新开辟一个线程继续工作。怎样让run()方法结束呢?一般可用一个标志告诉线程什么时候通过退出自己的run()方法来中止自己的执行。2:将线程暂停或继续,不使用suspend()

29、和resume(),可在Thread 类中置入一个标志,指出线程应该活动还是挂起。假设标志指出线程应该挂起,便用wait()命其进入等待状态。假设标志指出线程应当恢复,则用一个notify()重新启动线程。3:不推荐使用stop()来终止阻塞的线程,而应换用由Thread 提供的interrupt()方法,以便中止并退出堵塞的代码。3.6 进程平安3.6.1 进程概述进程是一个执行中的程序,对每一个进程来说,都有自己独立的一片内存空间和一组系统资源。进程由进程控制块、程序段、数据段三局部组成。在进程概念中,每一个进程的内部数据和状态都是完全独立的。一个进程可以包含假设干线程,线程可以帮助应用程

30、序同时做几件事(比方一个线程向磁盘写入文件,另一个则接收用户的按键操作并及时做出反响,互相不干扰)。进程也有运行、阻塞、就绪三种状态,并随一定条件而相互转化。3.6.2 进程平安问题由于进程的独立性,从应用的角度讲,进程平安比线程平安更受重视,一般针对已有的进程进行平安方面的控制。如:在系统平安中发现并去除病毒进程;在网络应用中,优化守护进程或端口扫描进程;等等。不过,从开发者编程的角度,进程的平安所需要考虑的问题和线程类似,但由于线程能够共享进程的资源,所以线程平安一般考虑的问题比进程平安多。不过,对于开发多个进程能够运行的系统软件如操作系统,进程的平安就应该重点考虑了。一般情况下,此时考虑

31、的问题和线程平安类似,因为在这种软件中,各个进程在使用系统有限的资源,和线程平安中考虑的问题类似,在此不再表达。小结本章主要针对线程和进程开发过程中的平安问题进行讲述。从开发者角度,首先讲解了线程的的基本机制,然后讲解线程操作过程中几个重要的平安问题:线程同步平安、线程协作平安、线程死锁、线程控制平安等。最后讲解了进程平安。练习1:将P03_05.java 中的同步代码写在一个同步函数中。2:线程1 首先用Pen 写字,然后用Pencil 写字;线程2 首先用Pencil 写字,然后用Pen 写字;编写一个因为线程1 等待Pencil,线程2 等待Pen 而造成死锁的例子,并提出解决方法。3:

32、两个线程,向空间有限的数组中写数据。写一段代码,具有数组溢出的平安隐患,并提出解决方案。4:界面上有个小红球,要求能够慢慢掉下来然后弹起来;为了逼真,当球在比较上方的时候,球比较大,球落下时,慢慢变小;在界面右下角有一个“暂停按钮,可以让动画暂停;动画暂停之后又可以点击按钮让动画继续运行。5:举例说明进程平安和线程平安问题所考虑的问题的不同之处?6:Oracle 数据库中,多个用户访问同一数据,可能会造成死锁,请你设计一个案例,进行测试。并观察其解决方法。7:很多语言中提供了定时器(Timer),让某个功能定时执行,该功能也可以用线程实现,比较两种方法的优劣。8:编写一个程序,每隔一秒,界面上

33、方落下来一个字母。字母落到界面底端,消失,这里怎样控制线程的开始和结束?9:飞机射击游戏中线程是怎样应用的?10:将P03_11.java 代码中同步段改为同步方法。w 9、静夜四无邻,荒居旧业贫。5 月-235 月-23Saturday,May 13,2023w 10、雨中黄叶树,灯下白头人。21:36:0621:36:0621:365/13/2023 9:36:06 PMw 11、以我独沈久,愧君相见频。5 月-2321:36:0621:36May-2313-May-23w 12、故人江海别,几度隔山川。21:36:0621:36:0621:36Saturday,May 13,2023w

34、13、乍见翻疑梦,相悲各问年。5 月-235 月-2321:36:0621:36:06May 13,2023w 14、他乡生白发,旧国见青山。13 五月 20239:36:06 下午21:36:065 月-23w 15、比不了得就不比,得不到的就不要。五月 239:36 下午5 月-2321:36May 13,2023w 16、行动出成果,工作出财富。2023/5/13 21:36:0621:36:0613 May 2023w 17、做前,能够环视四周;做时,你只能或者最好沿着以脚为起点的射线向前。9:36:06 下午9:36 下午21:36:065 月-23w 9、没有失败,只有暂时停止成功

35、!。5 月-235 月-23Saturday,May 13,2023w 10、很多事情努力了未必有结果,但是不努力却什么改变也没有。21:36:0621:36:0621:365/13/2023 9:36:06 PMw 11、成功就是日复一日那一点点小小努力的积累。5 月-2321:36:0621:36May-2313-May-23w 12、世间成事,不求其绝对圆满,留一份缺乏,可得无限完美。21:36:0621:36:0621:36Saturday,May 13,2023w 13、不知香积寺,数里入云峰。5 月-235 月-2321:36:0621:36:06May 13,2023w 14、意

36、志坚强的人能把世界放在手中像泥块一样任意揉捏。13 五月 20239:36:06 下午21:36:065 月-23w 15、楚塞三湘接,荆门九派通。五月 239:36 下午5 月-2321:36May 13,2023w 16、少年十五二十时,步行夺得胡马骑。2023/5/13 21:36:0621:36:0613 May 2023w 17、空山新雨后,天气晚来秋。9:36:06 下午9:36 下午21:36:065 月-23w 9、杨柳散和风,青山澹吾虑。5 月-235 月-23Saturday,May 13,2023w 10、阅读一切好书如同和过去最杰出的人谈话。21:36:0621:36:

37、0621:365/13/2023 9:36:06 PMw 11、越是没有本领的就越加自命非凡。5 月-2321:36:0621:36May-2313-May-23w 12、越是无能的人,越喜欢挑剔别人的错儿。21:36:0621:36:0621:36Saturday,May 13,2023w 13、知人者智,自知者明。胜人者有力,自胜者强。5 月-235 月-2321:36:0621:36:06May 13,2023w 14、意志坚强的人能把世界放在手中像泥块一样任意揉捏。13 五月 20239:36:06 下午21:36:065 月-23w 15、最具挑战性的挑战莫过于提升自我。五月 239

38、:36 下午5 月-2321:36May 13,2023w 16、业余生活要有意义,不要越轨。2023/5/13 21:36:0621:36:0613 May 2023w 17、一个人即使已登上顶峰,也仍要自强不息。9:36:06 下午9:36 下午21:36:065 月-23MOMODA POWERPOINTLorem ipsum dolor sit amet,consectetur adipiscing elit.Fusce id urna blandit,eleifend nulla ac,fringilla purus.Nulla iaculis tempor felis ut cursus.感 谢 您 的 下 载 观 看专家告诉演讲完毕,谢谢观看!

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁