1. 程式人生 > >iOS開發-多執行緒程式設計技術(Thread、Cocoa operations、GCD)

iOS開發-多執行緒程式設計技術(Thread、Cocoa operations、GCD)

簡介

在軟體開發中,多執行緒程式設計技術被廣泛應用,相信多執行緒任務對我們來說已經不再陌生了。有了多執行緒技術,我們可以同做多個事情,而不是一個一個任務地進行。比如:前端和後臺作互動、大任務(需要耗費一定的時間和資源)等等。也就是說,我們可以使用執行緒把佔據時間長的任務放到後臺中處理,而不影響到使用者的使用。

執行緒間通訊

有一個非常重要的佇列,就是主佇列。在這個佇列中處理多點觸控及所有與UI相關操作等等。它非常特殊,原因有兩點。一是我們絕對不想它阻塞,我們不會將需要執行很長時間的任務放在主佇列上執行。二是我們將其用於所有與UI相關的同步,也就是執行緒間通訊需要注意的地方。所有有可能會使螢幕UI發生變化的,都應放在主佇列上執行。

執行緒的定義:

每個正在系統上執行的程式都是一個程序。每個程序包含一到多個執行緒。程序也可能是整個程式或者是部分程式的動態執行。執行緒是一組指令的集合,或者是程式的特殊段,它可以在程式裡獨立執行。也可以把它理解為程式碼執行的上下文。所以執行緒基本上是輕量級的程序,它負責在單個程式裡執行多工。通常由作業系統負責多個執行緒的排程和執行。

轉自百度百科:多執行緒

如果熟悉多執行緒程式設計技術這一塊的朋友們,可以去看關於多執行緒安全的文章,是我寫的另一篇文章”iOS開發-多執行緒開發之執行緒安全篇“;

IOS支援的多執行緒技術:

一、Thread:

二、Cocoa operations:

NSOperation類是一個抽象類,因為我們必須使用它的兩個子類。

————————————————————————————

三、Grand Central Dispatch (GCD):

一、Thread

我們可以使用NSTherad或NSObject類去呼叫:

1)顯式建立執行緒:NSThread

建立NSThread有兩個辦法

1.1)建立之後需要使用start方法,才會執行方法:

NSThread *threadAlloc = [[NSThread alloc] initWithTarget:self selector:@selector(threadAlloc) object
:nil]; [threadAlloc start];

1.2)建立並馬上執行方法:

[NSThread detachNewThreadSelector:@selector(threadAlloc:) toTarget:self withObject:nil];

2)隱式建立執行緒:NSObject

我們也可以使用NSObject類的方法直接呼叫方法

[self performSelectorInBackground:@selector(threadAlloc) withObject:nil];

取消執行緒的方法:

實際上並沒有真正提供取消執行緒的API。蘋果提供了一個cancel的api,但它不能作用於取消執行緒,它只能改變執行緒的執行狀態。我們可以使用它來進行條件判斷。

- (void)threadCancel
{
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadCancelNow) object:nil];
    [thread start];
}

- (void)threadCancelNow
{
    int a = 0;
    while (![[NSThread currentThread] isCancelled]) {
        NSLog(@"a - %d", a);
        a++;
        if (a == 5000) {
            NSLog(@"終止迴圈");
            [[NSThread currentThread] cancel];
            break;
        }
    }
}

程式效果:迴圈輸出5000次,執行緒就會被終止。

NSThread執行緒間通訊-呼叫主執行緒修改UI:

只需要傳遞一個selector和它的引數,withObject引數可以為nil,waitUntilDone代表是否要等待呼叫它的這個執行緒執行之後再將它從主佇列調出,並在主佇列上執行,通常設為NO,不需要等待。

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

NSThread相關屬性及方法:

// 獲取/設定執行緒的名字
@property (copy) NSString *name NS_AVAILABLE(10_5, 2_0);

/**
 *  獲取當前執行緒的執行緒物件
 *
 *  通過這個屬性可以檢視當前執行緒是第幾條執行緒,主執行緒為1。
 *  可以看到當前執行緒的序號及名字,主執行緒的序號為1,依次疊加。
 */
+ (NSThread *)currentThread;

// 執行緒休眠(秒)
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;

// 執行緒休眠,指定具體什麼時間休眠
+ (void)sleepUntilDate:(NSDate *)date;

// 退出執行緒 
// 注意:這裡會把執行緒物件銷燬!銷燬後就不能再次啟動執行緒,否則程式會崩潰。
+ (void)exit;

二、Cocoa operations

1)NSInvocationOperation

建立NSInvocationOperation執行緒,附帶一個NSString引數:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationAction:) object:@"abc"];
// 需要啟動執行緒,預設是不啟動的。
[operation start];

如在建立時定義了引數,那麼接收的時候,可以對sender進行轉換,如字串、陣列等:

- (void)invocationAction:(NSInvocationOperation *)sender
{
    NSLog(@"sender - %@", sender);      // 輸出params
    NSString *str = (NSString *)sender;
    NSLog(@"str - %@e", str);           // params
}

附帶一提,執行緒的普通建立一般為併發執行的,因為序列佇列是需要顯式建立的,如沒看見此類程式碼,那麼即是併發佇列執行緒,因此,上述程式碼也就是併發執行緒。關於併發和序列佇列(執行緒),我將會在下面詳細說明,我們繼續往下看。

你也可以使用NSOperationQueue來建立一個執行緒佇列,用來新增子執行緒:

NSOperationQueue *invocationQueue = [[NSOperationQueue alloc] init];

// 執行緒A
NSInvocationOperation *invocationQ1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationAction:) object:@"invocationQ1"];

// 執行緒B
NSInvocationOperation *invocationQ2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationAction:) object:@"invocationQ2"];

// 往invocationQueue新增子執行緒
[invocationQueue addOperations:@[invocationQ1, invocationQ2] waitUntilFinished:YES];

必須使用addOperations:方法把執行緒新增至佇列,不然執行緒不會執行,佇列是並行執行。或者,你也可以使用addOperation:方法新增單個執行緒。

2)NSBlockOperation

建立NSBlockOperation

// 建立執行緒任務
NSBlockOperation *blockOperation = [NSBlockOperation
                                    blockOperationWithBlock:^{
                                        [NSThread sleepForTimeInterval:2];
                                        NSLog(@"one - %@", [NSThread currentThread]);
                                    }];;// 執行執行緒任務
[blockOperation start];

注意:這會在當前的執行緒中執行,因為它是根據呼叫的執行緒所決定的。

比方說你在主執行緒中執行它,那麼它就是在主執行緒中執行任務。如果你是在子執行緒中執行它,那麼它就是在子執行緒中執行任務。

做個簡單的實驗,我們新建一條子執行緒,然後在子執行緒裡呼叫NSBlockOperation

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSBlockOperation *blockOperation = [NSBlockOperation
                                        blockOperationWithBlock:^{
                                            [NSThread sleepForTimeInterval:2];
                                            NSLog(@"one - %@", [NSThread currentThread]);
                                            // print: one - <NSThread: 0x7f8ac2e1d0b0>{number = 2, name = (null)}
                                        }];;
    
    [blockOperation start];
});

它將列印:one - <NSThread: 0x7f8ac2e1d0b0>{number = 2, name = (null)},因此這個理論是正確的

我們也可以使它併發執行,通過使用addExecutionBlock方法新增多個Block,這樣就能使它在主執行緒和其它子執行緒中工作。

NSBlockOperation *blockOperation = [NSBlockOperation
                                    blockOperationWithBlock:^{
                                        NSLog(@"one - %@", [NSThread currentThread]);
                                    }];;

[blockOperation addExecutionBlock:^{
    NSLog(@"two - %@", [NSThread currentThread]);
}];

[blockOperation addExecutionBlock:^{
    NSLog(@"three - %@", [NSThread currentThread]);
}];

[blockOperation addExecutionBlock:^{
    NSLog(@"four - %@", [NSThread currentThread]);
}];

[blockOperation start];

它將列印:

two - <NSThread: 0x7fea8a70b000>{number = 3, name = (null)}
one - <NSThread: 0x7fea8a558a40>{number = 4, name = (null)}
four - <NSThread: 0x7fea8a406b90>{number = 1, name = main}
three - <NSThread: 0x7fea8a436e40>{number = 2, name = (null)}

大家都看到,即使我們通過使用addExecutionBlock方法使它併發執行任務,但是它也依舊會在主執行緒執行,因此我們就需要使用NSOperationQueue了。

3)NSOperationQueue

這裡介紹一下NSOperation的依賴關係,依賴關係會影響執行緒的執行順序:

// 建立操作佇列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 執行緒A
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"op1");
    [NSThread sleepForTimeInterval:2];
}];

// 執行緒B
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"op2");
}];

// 執行緒C
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"op3");
    [NSThread sleepForTimeInterval:2];
}];

// 執行緒B依賴執行緒C,也就是等執行緒C執行完之後才會執行執行緒B
[op2 addDependency:op3];
// 執行緒C依賴執行緒A,同上,只不過依賴物件改成了執行緒A
[op3 addDependency:op1];

// 為佇列新增執行緒
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];

當你沒新增依賴時,佇列是並行執行的。

注意:依賴關係可以多重依賴,但不要建立迴圈依賴。

Cocoa operations執行緒間通訊-呼叫主執行緒修改UI:

// 建立執行緒物件(併發)
NSBlockOperation *blockOperation = [[NSBlockOperation alloc] init];

// 新增新的操作
[blockOperation addExecutionBlock:^{
    NSLog(@"two - %@", [NSThread currentThread]);
}];

// 新增新的操作
[blockOperation addExecutionBlock:^{
    NSLog(@"three - %@", [NSThread currentThread]);
    // 在主執行緒修改UI
    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    [queue addOperationWithBlock:^{
        [self editUINow];
    }];
}];

[blockOperation start];

NSOperation方法及屬性:

// 設定執行緒的最大併發數
@property NSInteger maxConcurrentOperationCount;

// 執行緒完成後呼叫的Block
@property (copy) void (^completionBlock)(void);

// 取消執行緒
- (void)cancel;

只列舉上面那些,其它的方法就不全列出來了。

注意:在NSOperationQueue類中,我們可以使用cancelAllOperations方法取消所有的執行緒。這裡需要說明一下,不是執行cancelAllOperations方法時就會馬上取消,是等當前佇列執行完,下面的佇列不會再執行。

三、Grand Central Dispatch (GCD)

1)GCD非同步執行緒的建立:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"執行緒 - %@", [NSThread currentThread]);
});

GCD也可以建立同步的執行緒,只需要把async改成sync即可。

2)重複執行執行緒:dispatch_apply

以下程式碼會執行4次:

dispatch_apply(4, DISPATCH_QUEUE_PRIORITY_DEFAULT, ^(size_t index) {
    // index則為執行的次數 0開始遞增
    NSLog(@"one - %ld", index);
});

index引數為執行的次數,從0開始遞增。

其中需要注意的是,每次執行都會新開闢一條子執行緒,因為是非同步的原因,它們不會是順序的。

[657:159159] one - 0, thread - <NSThread: 0x100110b50>{number = 1, name = main}
[657:159191] one - 2, thread - <NSThread: 0x103800000>{number = 2, name = (null)}
[657:159192] one - 3, thread - <NSThread: 0x100112b90>{number = 3, name = (null)}
[657:159190] one - 1, thread - <NSThread: 0x100501180>{number = 4, name = (null)}

然而,GCD還有一次性執行的方法:

dispatch_once_t once;
dispatch_once(&once, ^{
    NSLog(@"once - %@", [NSThread currentThread]); // 主執行緒
});

它通常用於建立單例。

3)操作佇列:dispatch_queue_create

使用GCD也能建立序列佇列,具體程式碼如下:

/**
 *  GCD建立序列佇列
 *
 *  @param "com.GarveyCalvin.queue"  佇列字串標識
 *  @param DISPATCH_QUEUE_CONCURRENT 可選的,可以是NULL
 *
 *  @return dispatch_queue_t
 */
dispatch_queue_t queue = dispatch_queue_create("com.GarveyCalvin.queue", DISPATCH_QUEUE_CONCURRENT);

// 執行緒A
dispatch_async(queue, ^{
    [NSThread sleepForTimeInterval:1];
    NSLog(@"sleep async - %@", [NSThread currentThread]);
});

// 執行緒B
dispatch_barrier_async(queue, ^{
    [NSThread sleepForTimeInterval:3];
    NSLog(@"sleep barrier2 - %@", [NSThread currentThread]);
});

// 執行緒C
dispatch_async(queue, ^{
    NSLog(@"async");
});

執行效果:以上會先執行 執行緒A-》執行緒B-》執行緒C,它是一個序列佇列。

dispatch_queue_create的第二個引數:

1)DISPATCH_QUEUE_SERIAL(序列)

2)DISPATCH_QUEUE_CONCURRENT(併發)

4)GCD群組通知:dispatch_group_t

GCD的高階用法,等所有執行緒都完成工作後,再作通知。

// 建立群組
dispatch_group_t group = dispatch_group_create();

// 執行緒A
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"group1");
    [NSThread sleepForTimeInterval:2];
});

// 執行緒B
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"group2");
});

// 待群組裡的執行緒都完成之後呼叫的通知
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"group success");
});

群組裡的執行緒也是並行佇列。執行緒A和執行緒B都執行完之後,會呼叫通知列印group success。

5)GCD實現計時器

__block int time = 30;
CGFloat reSecond = 1.0;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, reSecond * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(timer, ^{
    time--;
    NSLog(@"%d", time);
    if (time == 0) {
        dispatch_source_cancel(timer);
    }
});
dispatch_resume(timer);

程式碼效果:建立了一個計時器,計時器執行30秒,每過一秒會呼叫一次block,我們可以在block裡面寫程式碼。因為dispatch_source_t預設是掛起狀態,因此我們使用時需要使用dispatch_resume方法先恢復,不然執行緒不會執行。

GCD執行緒間通訊-呼叫主執行緒修改UI:

有時候我們請求後臺作資料處理,資料處理是非同步的,資料處理完成後需要更新UI,這時候我們需要切換到主執行緒修改UI,例子如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"非同步資料處理 - %@", [NSThread currentThread]);
    [NSThread sleepForTimeInterval:2];
    NSLog(@"資料處理完成");
    
    // 呼叫主執行緒更新UI
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"更新UI - %@", [NSThread currentThread]);
        [self editUINow];
    });
});

因為是在主執行緒修改UI,所以我們最好是使用同步的GCD方法dispatch_sync。但這還不夠,我們還需要使用dispatch_get_main_queue()方法來獲得主執行緒,之後就是作UI的更新工作了。

GCD方法及屬性:

// 獲取主執行緒
dispatch_get_main_queue()

// 建立佇列:第一個引數是佇列的名稱,它會出現在除錯程式等之中,是個內部名稱。第二個引數代表它是序列佇列還是並併發佇列,NULL代表序列佇列。
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

// 建立非同步排程佇列
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

// 恢復佇列
void dispatch_resume(dispatch_object_t object);

// 暫停佇列
void dispatch_suspend(dispatch_object_t object);

小結:本文主要介紹了IOS三種執行緒對比及其使用方法。需要特別注意的是,在修改任何有關於UI的東西,我們必須要切換至主執行緒,在主執行緒裡修改UI,避免不必要的麻煩產生。蘋果是推薦我們使用GCD,因為GCD是這三種裡面抽象級最高的,使用起來也簡單,也是消耗資源最低的,並且它執行效率比其它兩種都高。因此,能夠使用GCD的地方,儘量使用GCD。

6)後臺執行

使用block的另一個好處是可以讓程式在後臺較久地執行。在以前,當應用被按Home鍵退出後,應用僅有最多5秒的時間做一些儲存或清理資源的工作。 但是如果使用GCD,你可以讓你的應用最多有10分鐘的時間在後臺長久執行。這個時間可以用來做各種事情,包括清理本地快取、傳送統計資料等工作。

AppDelegate.h
@interface AppDelegate ()

@property (assign, nonatomic) UIBackgroundTaskIdentifier backGroundUpdate;

@end

AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application {
    [self beginBackGroundUpdate];
   // 需要長久執行的程式碼
    [self endBackGroundUpdate];
}

- (void)beginBackGroundUpdate
{
    self.backGroundUpdate = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [self endBackGroundUpdate];
    }];
}

- (void)endBackGroundUpdate
{
    [[UIApplication sharedApplication] endBackgroundTask:self.backGroundUpdate];
    self.backGroundUpdate = UIBackgroundTaskInvalid;
}

建議大家在真機上測試,因為筆者在模擬器測試了24分鐘還有效。

7)延遲執行

如果我們想要某段程式碼延遲執行,那麼可以使用dispatch_after ,但是有一個缺點是,當提交程式碼後(程式碼執行後),我們不能取消它,它將會執行。另外,我們可以使用 NSTimer 進行延時操作,值得一提,它是可以被取消的。

dispatch_time_t time_t = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC));
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_after(time_t, queue, ^{
    NSLog(@"hahalo");
});

比較多執行緒技術

一、Thread: 

優點:量級較輕。

缺點:需要自己管理執行緒的生命週期,執行緒同步。執行緒同步對資料的加鎖會有一定的系統開銷。

二、Cocoa operations:

優點:不需要關心執行緒管理,資料同步的事情,可以把精力放在自己需要執行的操作上。

三、Grand Central Dispatch (GCD):

優點:GCD基於C的API,非常底層,可以充分利用多核,能夠輕鬆在多核系統上高效執行併發程式碼,也是蘋果推薦使用的多執行緒技術。

本文參考:

全面掌握iOS多執行緒攻略 —— PS:這個攻略較多,但是有很多重複的內容。

博文作者:GarveyCalvin

本文版權歸作者和部落格園共有,歡迎轉載,但須保留此段宣告,並給出原文連結,謝謝合作!

相關推薦

iOS開發執行程式設計技術ThreadCocoa operationsGCD

簡介 在軟體開發中,多執行緒程式設計技術被廣泛應用,相信多執行緒任務對我們來說已經不再陌生了。有了多執行緒技術,我們可以同做多個事情,而不是一個一個任務地進行。比如:前端和後臺作互動、大任務(需要耗費一定的時間和資源)等等。也就是說,我們可以使用執行緒把佔據時間長的任務放到後臺中處理,而不影響到使用者的使用

iOS開發執行開發執行安全篇

前言:一塊資源可能會被多個執行緒共享,也就是多個執行緒可能會訪問同一塊資源,比如多個執行緒訪問同一個物件、同一個變數、同一個檔案和同一個方法等。因此當多個執行緒訪問同一塊資源時,很容易會發生資料錯誤及資料不安全等問題。因此要避免這些問題,我們需要使用“執行緒鎖”來實現。 一、使用關鍵字 優

iOS執行程式設計技術NSThreadCocoa NSOperationGCD三者使用詳解

簡介 iOS有三種多執行緒程式設計的技術,分別是:(一)NSThread (二)Cocoa NSOperation (三)GCD(全稱:Grand Central Dispatch)三種方式的優缺點介紹: 1)NSThread優點:NSThread 比其他兩個輕量級缺點

【C/C++開發執行程式設計中的join函式

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # codi

iOS開發執行NSThread

之前的文章中介紹,多執行緒能夠提高應用程式的執行效率,把耗時的操作放在子執行緒中執行,這樣不會阻塞主執行緒的執行,不會給使用者“卡”的體驗。本文主要介紹多執行緒程式設計的第一種方式。 由於pthread是底層的多執行緒程式設計API,對於pthread,瞭解如何讓建立子執行

Android開發執行程式設計Thread和Runnable使用

Android可有兩種方式實現多執行緒,一種是繼承Thread類,一種是實現Runnable介面;前者只要繼承了Thread類同時覆寫了本類中的run()方法就可以實現多執行緒操作了,但是Java中一個類只能繼承一個父類,這是這種方式的侷限性,後者只需要實現一個介面而已,

Android開發執行的操作方式Thread,TimerTask,AsyncTask

雨鬆MOMO原創文章如轉載,請註明:轉載至我的獨立域名部落格雨鬆MOMO程式研究院,原文地址:http://www.xuanyusong.com/archives/344 Android研究院之遊戲開發多執行緒(十六)   遊戲開發與軟體開發多執行緒的重要性  &

執行程式設計學習1物件及變數的併發訪問

程序:計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統結構的基礎。 執行緒:在程序中獨立執行的子任務。 在java中以下3種方法可以終止正在執行的執行緒: 1) 使用退出標誌,使執行緒正常退出,也就是當run方法完成後執行緒終

Linux下的執行程式設計執行的同步與互斥

一、什麼叫做執行緒的同步與互斥?為什麼需要同步與互斥? 1、同步與互斥 互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。 同步:是指在互斥的基礎上(大多數情況),通過其它機制

Qt執行程式設計總結

Qt對執行緒提供了支援,基本形式有獨立於平臺的執行緒類、執行緒安全方式的事件傳遞和一個全域性Qt庫互斥量允許你可以從不同的執行緒呼叫Qt方法。 這個文件是提供給那些對多執行緒程式設計有豐富的知識和經驗的聽眾的。推薦閱讀: 警告:所有的GUI類(比如,QWidget和它的

C++11執行程式設計系列實戰

C++11 新標準中引入了多個頭檔案來支援多執行緒程式設計,他們分別是<atomic> ,<thread>,<mutex>,<condition_variable>和<future>。 <

Qt執行程式設計總結所有GUI物件都是執行不安全的

Qt對執行緒提供了支援,基本形式有獨立於平臺的執行緒類、執行緒安全方式的事件傳遞和一個全域性Qt庫互斥量允許你可以從不同的執行緒呼叫Qt方法。 這個文件是提供給那些對多執行緒程式設計有豐富的知識和經驗的聽眾的。推薦閱讀: 警告:所有的GUI類(比如,QWidget和它的子類),作業系統核心類(比如,QPr

安卓開發執行斷點下載

效果圖: Log: 網上關於講解挺多的,我這裡不講解了,不懂的可以評論留言,從問題中解決問題 我可以說一下我解決問題的方式,將複雜問題劃分成多個簡單的問題 多執行緒下載一:請點選這裡 多執行緒下載二:請點選這裡 許可權: <uses

linux環境下ssl執行程式設計例項整理

服務端: #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <errno.h> #ifndef    _WIN32 #include <

C++執行程式設計回顧1C11

1、執行緒join&detach,程式碼示例如下(實測,可用): #include <iostream> #include <thread> #include <windows.h>//列印執行緒號所引,僅限Wi

C++11併發/執行程式設計系列2

std::thread詳解 std::thread在標頭檔案<thread>中宣告,因此使用 std::thread 時需要包含 <thread>標頭檔案。 default(1) thread() noexcept;

執行程式設計入門

多執行緒簡介 1: 什麼是多執行緒 多執行緒,是指從軟體或者硬體上實現多個執行緒併發執行的技術。具有多執行緒能力的計算機因有硬體支援而能夠在同一時間執行多於一個執行緒,進而提升整體處理效能。具有這種能力的系統包括對稱多處理機、多核心處理器以及晶片級多處理

執行程式設計總結——條件變數和互斥鎖

#include <stdio.h> #include <pthread.h> #include <error.h> #include <assert.h> #include <stdlib.h> typedef int DataType; typ

Windows 執行程式設計入門1

看了網上一些說法,總結以下幾點: 1:從C++11開始,標準庫裡已經包含了對執行緒的支援,即: std::thread 2:C++本身還支援pthread這個API來進行多執行緒程式設計。 3:自己常用Windows程式設計,還是擁抱一下C++11吧

畢向東講解—7.執行安全問題同步函式的鎖this驗證

package day6; /**  * 同步程式碼塊和同步函式  * 對同步函式的鎖是否為this的驗證  *  * @author mzy  *  *  因為本身同步程式碼塊我們傳入的鎖物件是當前物件this  *  只要同步函式的鎖物件是this的話,那麼我們的賣票