c++thread里暂停线程_多线程技术
1.程序
程序(Program)”是一個靜態的概念,一般對應于操作系統中的一個可執行文件,比如:我們要啟動酷狗聽音樂,則對應酷狗的可執行程序。當我們雙擊酷狗,則加載程序到內存中,開始執行該程序,于是產生了“進程”。
2.進程
執行中的程序叫做進程(Process),是一個動態的概念。現代的操作系統都可以同時啟動多個進程。比如:我們在用酷狗聽音樂,也可以使用eclipse寫代碼,也可以同時用瀏覽器查看網頁。進程具有如下特點:
1. 進程是程序的一次動態執行過程, 占用特定的地址空間。
2. 每個進程由3部分組成:cpu、data、code。每個進程都是獨立的,保有自己的cpu時間,代碼和數據,即便用同一份程序產生好幾個進程,它們之間還是擁有自己的這3樣東西,這樣的缺點是:浪費內存,cpu的負擔較重。
3. 多任務(Multitasking)操作系統將CPU時間動態地劃分給每個進程,操作系統同時執行多個進程,每個進程獨立運行。以進程的觀點來看,它會以為自己獨占CPU的使用權。
3.線程
一個進程可以產生多個線程。同多個進程可以共享操作系統的某些資源一樣,同一進程的多個線程也可以共享此進程的某些資源(比如:代碼、數據),所以線程又被稱為輕量級進程(lightweight process)。
1. 一個進程內部的一個執行單元,它是程序中的一個單一的順序控制流程。
2. 一個進程可擁有多個并行的(concurrent)線程。
3. 一個進程中的多個線程共享相同的內存單元/內存地址空間,可以訪問相同的變量和對象,而且它們從同一堆中分配對象并進行通信、數據交換和同步操作。
4. 由于線程間的通信是在同一地址空間上進行的,所以不需要額外的通信機制,這就使得通信更簡便而且信息傳遞的速度也更快。
5. 線程的啟動、中斷、消亡,消耗的資源非常少。
4.線程和進程的區別
1. 每個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有較大的開銷。
2. 線程可以看成是輕量級的進程,屬于同一進程的線程共享代碼和數據空間,每個線程有獨立的運行棧和程序計數器(PC),線程切換的開銷小。
3. 線程和進程最根本的區別在于:進程是資源分配的單位,線程是調度和執行的單位。
4. 多進程: 在操作系統中能同時運行多個任務(程序)。
5. 多線程: 在同一應用程序中有多個順序流同時執行。
6. 線程是進程的一部分,所以線程有的時候被稱為輕量級進程。
7. 一個沒有線程的進程是可以被看作單線程的,如果一個進程內擁有多個線程,進程的執行過程不是一條線(線程)的,而是多條線(線程)共同完成的。
8. 系統在運行的時候會為每個進程分配不同的內存區域,但是不會為線程分配內存(線程所使用的資源是它所屬的進程的資源),線程組只能共享資源。那就是說,除了CPU之外(線程在運行的時候要占用CPU資源),計算機內部的軟硬件資源的分配與線程無關,線程只能共享它所屬進程的資源。
5.進程與程序的區別
程序是一組指令的集合,它是靜態的實體,沒有執行的含義。而進程是一個動態的實體,有自己的生命周期。一般說來,一個進程肯定與一個程序相對應,并且只有一個,但是一個程序可以有多個進程,或者一個進程都沒有。除此之外,進程還有并發性和交往性。簡單地說,進程是程序的一部分,程序運行的時候會產生進程。
6.Java中如何實現多線程
1.通過繼承Thread類實現多線程
繼承Thread類實現多線程的步驟:
1. 在Java中負責實現線程功能的類是java.lang.Thread 類。
2. 可以通過創建 Thread的實例來創建新的線程。
3. 每個線程都是通過某個特定的Thread對象所對應的方法run( )來完成其操作的,方法run( )稱為線程體。
4. 通過調用Thread類的start()方法來啟動一個線程。
實例:
public class TestThread extends Thread {//自定義類繼承Thread類//run()方法里是線程體public void run() {for (int i = 0; i < 10; i++) {System.out.println(this.getName() + ":" + i);//getName()方法是返回線程名稱}}public static void main(String[] args) {TestThread thread1 = new TestThread();//創建線程對象thread1.start();//啟動線程TestThread thread2 = new TestThread();thread2.start();} } 2.通過Runnable接口實現多線程在開發中,我們應用更多的是通過Runnable接口實現多線程。這種方式克服了方法1中實現線程類的缺點,即在實現Runnable接口的同時還可以繼承某個類。所以實現Runnable接口的方式要通用一些。 實例: public class TestThread2 implements Runnable {//自定義類實現Runnable接口;//run()方法里是線程體;public void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + ":" + i);}}public static void main(String[] args) {//創建線程對象,把實現了Runnable接口的對象作為參數傳入;Thread thread1 = new Thread(new TestThread2());thread1.start();//啟動線程;Thread thread2 = new Thread(new TestThread2());thread2.start();} }7.線程狀態
一個線程對象在它的生命周期內,需要經歷5個狀態。
? 新生狀態(New)
用new關鍵字建立一個線程對象后,該線程對象就處于新生狀態。處于新生狀態的線程有自己的內存空間,通過調用start方法進入就緒狀態。
? 就緒狀態(Runnable)
處于就緒狀態的線程已經具備了運行條件,但是還沒有被分配到CPU,處于“線程就緒隊列”,等待系統為其分配CPU。就緒狀態并不是執行狀態,當系統選定一個等待執行的Thread對象后,它就會進入執行狀態。一旦獲得CPU,線程就進入運行狀態并自動調用自己的run方法。有4中原因會導致線程進入就緒狀態:
1. 新建線程:調用start()方法,進入就緒狀態;
2. 阻塞線程:阻塞解除,進入就緒狀態;
3. 運行線程:調用yield()方法,直接進入就緒狀態;
4. 運行線程:JVM將CPU資源從本線程切換到其他線程。
? 運行狀態(Running)
在運行狀態的線程執行自己run方法中的代碼,直到調用其他方法而終止或等待某資源而阻塞或完成任務而死亡。如果在給定的時間片內沒有執行結束,就會被系統給換下來回到就緒狀態。也可能由于某些“導致阻塞的事件”而進入阻塞狀態。
? 阻塞狀態(Blocked)
阻塞指的是暫停一個線程的執行以等待某個條件發生(如某資源就緒)。有4種原因會導致阻塞:
1. 執行sleep(int millsecond)方法,使當前線程休眠,進入阻塞狀態。當指定的時間到了后,線程進入就緒狀態。
2. 執行wait()方法,使當前線程進入阻塞狀態。當使用nofity()方法喚醒這個線程后,它進入就緒狀態。
3. 線程運行時,某個操作進入阻塞狀態,比如執行IO流操作(read()/write()方法本身就是阻塞的方法)。只有當引起該操作阻塞的原因消失后,線程進入就緒狀態。
4. join()線程聯合: 當某個線程等待另一個線程執行結束后,才能繼續執行時,使用join()方法。
? 死亡狀態(Terminated)
死亡狀態是線程生命周期中的最后一個階段。線程死亡的原因有兩個。一個是正常運行的線程完成了它run()方法內的全部工作; 另一個是線程被強制終止,如通過執行stop()或destroy()方法來終止一個線程(注:stop()/destroy()方法已經被JDK廢棄,不推薦使用)。
當一個線程進入死亡狀態以后,就不能再回到其它狀態了。
8.終止線程的典型方式
終止線程我們一般不使用JDK提供的stop()/destroy()方法(它們本身也被JDK廢棄了)。通常的做法是提供一個boolean型的終止變量,當這個變量置為false,則終止線程的運行。
終止線程的典型方法(重要)
public class TestThreadCiycle implements Runnable {String name;boolean live = true;// 標記變量,表示線程是否可中止;public TestThreadCiycle(String name) {super();this.name = name;}public void run() {int i = 0;//當live的值是true時,繼續線程體;false則結束循環,繼而終止線程體;while (live) {System.out.println(name + (i++));}}public void terminate() {live = false;}public static void main(String[] args) {TestThreadCiycle ttc = new TestThreadCiycle("線程A:");Thread t1 = new Thread(ttc);// 新生狀態t1.start();// 就緒狀態for (int i = 0; i < 100; i++) {System.out.println("主線程" + i);}ttc.terminate();System.out.println("ttc stop!");} }9.暫停線程執行sleep/yield
暫停線程執行常用的方法有sleep()和yield()方法,這兩個方法的區別是:
1. sleep()方法:可以讓正在運行的線程進入阻塞狀態,直到休眠時間滿了,進入就緒狀態。
2. yield()方法:可以讓正在運行的線程直接進入就緒狀態,讓出CPU的使用權。
1.暫停線程的方法-sleep()
public class TestThreadState {public static void main(String[] args) {StateThread thread1 = new StateThread();thread1.start();StateThread thread2 = new StateThread();thread2.start();} } //使用繼承方式實現多線程 class StateThread extends Thread {public void run() {for (int i = 0; i < 100; i++) {System.out.println(this.getName() + ":" + i);try {Thread.sleep(2000);//調用線程的sleep()方法;} catch (InterruptedException e) {e.printStackTrace();}}} }2.暫停線程的方法-yield()
public class TestThreadState {public static void main(String[] args) {StateThread thread1 = new StateThread();thread1.start();StateThread thread2 = new StateThread();thread2.start();} } //使用繼承方式實現多線程 class StateThread extends Thread {public void run() {for (int i = 0; i < 100; i++) {System.out.println(this.getName() + ":" + i);Thread.yield();//調用線程的yield()方法;}} }10.線程的聯合join()
線程A在運行期間,可以調用線程B的join()方法,讓線程B和線程A聯合。這樣,線程A就必須等待線程B執行完畢后,才能繼續執行。如下面示例中,“爸爸線程”要抽煙,于是聯合了“兒子線程”去買煙,必須等待“兒子線程”買煙完畢,“爸爸線程”才能繼續抽煙。
線程的聯合-join()
public class TestThreadState {public static void main(String[] args) {System.out.println("爸爸和兒子買煙故事");Thread father = new Thread(new FatherThread());father.start();} }class FatherThread implements Runnable {public void run() {System.out.println("爸爸想抽煙,發現煙抽完了");System.out.println("爸爸讓兒子去買包紅塔山");Thread son = new Thread(new SonThread());son.start();System.out.println("爸爸等兒子買煙回來");try {son.join();} catch (InterruptedException e) {e.printStackTrace();System.out.println("爸爸出門去找兒子跑哪去了");// 結束JVM。如果是0則表示正常結束;如果是非0則表示非正常結束System.exit(1);}System.out.println("爸爸高興的接過煙開始抽,并把零錢給了兒子");} }class SonThread implements Runnable {public void run() {System.out.println("兒子出門去買煙");System.out.println("兒子買煙需要10分鐘");try {for (int i = 1; i <= 10; i++) {System.out.println("第" + i + "分鐘");Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}System.out.println("兒子買煙回來了");} }11.獲取線程基本信息的方法
12.線程的優先級
1. 處于就緒狀態的線程,會進入“就緒隊列”等待JVM來挑選。
2. 線程的優先級用數字表示,范圍從1到10,一個線程的缺省優先級是5。
3. 使用下列方法獲得或設置線程對象的優先級。
int getPriority();
void setPriority(int newPriority);
注意:優先級低只是意味著獲得調度的概率低。并不是絕對先調用優先級高的線程后調用優先級低的線程。
總結
以上是生活随笔為你收集整理的c++thread里暂停线程_多线程技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NI 视觉入门软件介绍
- 下一篇: 阵列信号处理笔记-阵列信号处理基础