2011-05-06 41 views
6

của Apple dẫn Threading nói:Có cách nào để vào chế độ đa luồng cacao mà không tạo NSThread giả không?

Đối với các ứng dụng đa luồng, các khuôn khổ Cocoa sử dụng ổ khóa và các hình thức đồng bộ hóa nội bộ để đảm bảo chúng hoạt động một cách chính xác. Để ngăn chặn các ổ khóa từ hiệu suất xuống cấp trong trường hợp đơn luồng, tuy nhiên, Cocoa không tạo ra chúng cho đến khi ứng dụng sinh ra luồng mới đầu tiên của nó bằng cách sử dụng lớp NSThread. Nếu bạn sinh ra các luồng chỉ sử dụng các thủ tục luồng POSIX, Cocoa không nhận được các thông báo cần biết rằng ứng dụng của bạn hiện đa luồng. Khi điều đó xảy ra, các hoạt động liên quan đến khung công tác Cocoa có thể làm mất ổn định hoặc làm hỏng ứng dụng của bạn.

Để cho Cocoa biết rằng bạn dự định sử dụng nhiều luồng, tất cả những gì bạn phải làm là tạo ra một chuỗi đơn bằng cách sử dụng lớp NSThread và để cho chuỗi đó thoát ngay lập tức. Điểm nhập chủ đề của bạn không cần làm gì cả. Chỉ cần hành động sinh sản một luồng bằng NSThread là đủ để đảm bảo rằng các khóa cần thiết bởi các khung công tác Cocoa được đưa ra.

Trong ứng dụng iOS của tôi, tôi đang bắt đầu một số pthreads từ mã C++ ngay từ đầu. Để đảm bảo ứng dụng hoạt động đúng, theo tài liệu ở trên, tôi tạo một NSThread giả mạo không thực hiện được gì. Tôi không thích tạo ra mã vô dụng như vậy (thường là WTF, khi bạn đọc nó lần đầu tiên) và tôi muốn tránh làm như vậy. Có cách nào tốt hơn để đưa ứng dụng của tôi vào chế độ đa luồng không?

+0

Nó sẽ giúp để xem mã nơi bạn tạo NSThread. Bạn đang gọi "bắt đầu" trên chủ đề? – pzearfoss

Trả lời

3

Nếu có, không công khai và có thể không ổn định.

Nếu bạn đang nhấn WTF trong mã của mình, hãy đổi tên và kích hoạt lại mọi thứ để có ý nghĩa. Vì bạn cần một đối tượng giả với một selector giả là tốt, bạn chỉ có thể thêm một lớp throwaway như CocoaMultithreading và sau đó gửi nó nhắn +beginMultithreading:

@interface CocoaMultithreading : NSObject 
+ (void)beginMultithreading; 
@end 

int 
main(void) { 
    [CocoaMultithreading beginMultithreading]; 
    /* now do whatever you want */ 
    return EXIT_SUCCESS; 
} 

@implementation CocoaMultithreading 
+ (void)dummyThread:(id)unused 
{ 
    (void)unused; 
} 

+ (void)beginMultithreading 
{ 
    [NSThread detachNewThreadSelector:@selector(dummyThread:) 
      toTarget:self withObject:nil]; 
} 
@end 

Đó nên là đủ rõ ràng.

ETA: Alexander Staubo chỉ ra rằng, kể từ khi OS X 10.5/iOS 2.0, bạn có thể gọi phương thức -start trên một NSThread trực tiếp, vì vậy cách rất đơn giản để lật trên Cocoa đa luồng sẽ là:

void XXXActivateCocoaMultithreading(void) { [[NSThread new] start]; } 

Sau đó, trong main chức năng của bạn:

XXXActivateCocoaMultithreading(); 

Đó là rõ ràng, cũng như, nhưng xa le ss lộn xộn. (Các XXX là có để nhắc nhở bạn tiền tố không tĩnh chức năng. Kể từ khi các chức năng tĩnh thường trở thành không tĩnh tại một số điểm, tiền tố tất cả từ đầu là một động thái tốt.)

+0

Thực ra, có vẻ như thế này là đủ: '[[NSThread new] start];'. Sau đó, '[NSThread isMultiThreaded]' trả về 'YES'. –

+0

@AlexanderStaubo Nice! '-start' đã được thêm vào' NSThread' trong OS X 10.5 và đã có trong iOS từ 2.0, do đó, đừng lo lắng ở đó. Nỗi lo duy nhất của tôi là có thể khai thác hành vi không xác định khi nói đến những gì 'main' làm trên một cổ phiếu' NSThread'. Tôi thấy đề cập trong các tài liệu 'NSThread' của" mặc định 'main'", nhưng không có thảo luận thực sự về những gì nó sẽ làm gì nếu bạn không ghi đè nó trong một lớp con hoặc đặt mục tiêu và chọn. Nếu ai đó đồng ý với điều đó, thì đó là cách đơn giản nhất 100%, mặc dù họ vẫn nên thêm một cái gì đó để giải thích tại sao họ ngẫu nhiên sa thải một sợi giả. –

+0

Dường như NSThread chỉ bỏ qua các bộ chọn không tồn tại. Trong phiên bản ObjC trước đó, nó phát ra một cảnh báo cho stderr, trong ObjC 2.0 có vẻ như nó im lặng. (Thực sự mong muốn Xcode đến với các nguồn khung cốt lõi. Cố gắng tháo rời nền tảng lib đã khiến tôi không biết gì nhanh chóng.) –

Các vấn đề liên quan