2010-01-07 31 views
6

Tôi đang tìm cách để tạo phần còn lại của lát thời gian được lập lịch của luồng thực hiện đến một luồng khác. Có chức năng SwitchToThread trong WINAPI, nhưng nó không cho phép người gọi chỉ định chuỗi mà nó muốn chuyển sang. Tôi duyệt MSDN một thời gian và không tìm thấy bất cứ điều gì mà sẽ cung cấp chỉ đó.WIN32: Thực hiện thực hiện cho một chuỗi khác (đã cho)

Đối với một người quản trị hệ thống nội bộ, giống như tôi, có vẻ như là chuỗi năng suất sẽ có thể chỉ định luồng nào nó muốn truyền thực thi đến. Có thể hay chỉ là trí tưởng tượng của tôi?

+1

Thậm chí nếu bạn có thể làm điều này, nó sẽ là một ý tưởng rất tồi tệ. Bạn sẽ có hiệu quả viết lại lịch trình hệ điều hành bên trong ứng dụng của riêng bạn. Không tốt có thể đến từ cố gắng để làm như vậy ở điều! –

+0

@All: đã đồng ý, việc này có thể dẫn đến tình huống mà các chủ đề khác (ví dụ: các chủ đề quan trọng của hệ thống) sẽ bị bỏ đói và là một ý tưởng tồi nói chung. @ChrisW, @dsolimano: Tôi đã nghĩ về các loại sợi, nhưng một sợi chỉ có thể lên lịch cho một sợi chạy trong ngữ cảnh của chuỗi lịch. Trong trường hợp cụ thể này, tôi cần thực thi mã của mình trên một chuỗi cụ thể (DirectX yêu cầu điều đó). @Miky, @Nikolai: cảm ơn đề xuất phương án thay thế - đó là những gì tôi đang tìm kiếm. –

+0

Tôi đề nghị bạn cũng nên đọc về "các thói quen" cho nhiều lý thuyết và ý tưởng bất khả tri hơn trong lĩnh vực này, mặc dù tôi nghĩ rằng bạn có lẽ là tốt nhất khi gắn bó với các khái niệm Win32, và có lẽ chủ đề chứ không phải là sợi. – martinr

Trả lời

7

Lý do bạn không thể mang bộ xử lý thời gian lát to a thread được chỉ định là Windows có ưu tiên lập kế hoạch hạt nhân trong đó khá nhiều nơi thuộc trách nhiệm và quyền hạn của lịch thời gian xử lý trong tay của hạt nhân và chỉ hạt nhân.

Vì các chủ đề như vậy không có bất kỳ kiểm soát nào khi chúng chạy, nếu chúng chạy và thậm chí ít hơn luồng nào được chuyển sang sau khi lát thời gian của chúng được tăng lên.

Tuy nhiên, có một vài cách bạn có thể ảnh hưởng đến bối cảnh chuyển mạch:

  • bằng cách tăng độ ưu tiên của một chủ đề nào đó bạn có thể lực scheduler để sắp xếp nó thường xuyên hơn trong gây thiệt hại cho chủ đề khác (rõ ràng là ngược lại cũng được áp dụng - bạn có thể giảm mức độ ưu tiên của các chủ đề khác)

  • bạn có thể mã quy trình của mình để đặt chuỗi ở chế độ đợi hạt nhân khi chúng không hoạt động đó là công việc. Khi sử dụng các cấu trúc chờ đợi thích hợp như các phần quan trọng, Mutexes, Semaphores và Timers, bạn có thể nói một cách hiệu quả hạt nhân rằng một luồng nhất định không cần phải được lên lịch cho đến khi một mã nhất định được đáp ứng.

Lưu ý: hiếm khi có một lý do bạn nên làm xáo trộn những ưu tiên nhiệm vụ nên sử dụng cẩn thận

1

này là không thể. Chỉ hạt nhân mới có thể quyết định mã nào chạy tiếp theo mặc dù bạn có thể ảnh hưởng đến nó bằng cách giảm các chuỗi không chờ đợi mà nó phải chọn để chạy tiếp theo và bằng cách đặt ưu tiên luồng với SetThreadPriority.

1

Bạn có thể sử dụng nguyên gốc đồng bộ hóa thông thường như sự kiện, dấu chấm phẩy, v.v. để tuần tự hóa hai chuỗi của bạn. Điều này không dưới bất kỳ hình thức nào ngăn hạt nhân lên lịch các chủ đề khác ở giữa hoặc song song trên một lõi CPU khác hoặc hầu như đồng thời trên cùng một lõi. Điều này là do tính chất preemtive multitasking của các hệ điều hành mục đích chung hiện đại.

2

Bạn có thể sử dụng 'sợi' thay vì 'chủ đề': ví dụ: có API Win32 có tên SwitchToFiber cho phép bạn chỉ định sợi được lên lịch.

1

Nếu bạn muốn lập lịch biểu của riêng mình trong Windows, bạn có thể sử dụng fibers, chủ yếu là các chuỗi mà bạn phải lên lịch cho chính mình. Tuy nhiên, cho rằng bạn mô tả mình là một giáo dân đến thế giới nội bộ hệ điều hành, đó có lẽ sẽ là một ý tưởng tồi, vì sợi là một cái gì đó của một tính năng tiên tiến.

+0

Này, nó không giống như tôi sẽ gây ra bất kỳ tác hại nghiêm trọng - luôn luôn có một cơ hội tốt để tìm hiểu và được ít hơn của một giáo dân. Học những điều mới là (gần như) không bao giờ là một ý tưởng tồi :) –

2

Hãy xem UMS (User-mode lịch) đề trong Windows 7

http://msdn.microsoft.com/en-us/library/dd627187(VS.85).aspx

+0

Ah, nó trông giống như một đọc rất thú vị. Thật không may tôi đang nhắm mục tiêu cả hai nền tảng 32 và 64 bit từ XP trở lên và không thể sử dụng nó. Xấu hổ làm sao. Cảm ơn bạn đã chỉ cho tôi điều đó! –

+0

UMS giải quyết vấn đề được nêu bật trong câu trả lời của Miky Dinescu. – rwong

2

Các chủ đề thứ hai chỉ có thể chờ đợi cho thread năng suất hoặc bằng cách gọi WaitForSingleObject() trên tay cầm của nó hoặc bỏ phiếu định kỳ GetExitCodeThread(). Các câu trả lời khác là chính xác về việc thay đổi các cơ chế lập kế hoạch của hệ điều hành - tốt hơn là thiết kế các luồng một cách chính xác ngay từ đầu.

0

Tôi có thể yêu cầu lý do tại sao bạn muốn sử dụng SwitchToThread không?

Nếu ví dụ đó là một số hình thức vì chuỗi x đang tính toán giá trị mà bạn muốn đợi trên chuỗi Y, thì tôi thực sự khuyên bạn nên xem Thư viện mẫu song song hoặc Thư viện đại lý không đồng bộ trong Visual Studio 2010 cho phép bạn thực hiện việc này với các khối nhắn (nhận vào một giá trị không đồng bộ) hoặc đơn giản là thông qua nhiệm vụ: chờ đợi một bộ các nhiệm vụ để hoàn thành và nội tuyến thực hiện của họ trong khi chờ đợi ...

//i.e. on an arbitrary thread 
task_group* tasks; 
tasks->run(.../some functor/) 

một cuộc gọi đến tasks- > wait() sẽ đợi và nội tuyến bất kỳ tác vụ nào đang chạy.

+0

Đối với phần "lý do" - tôi không nhớ chính xác kịch bản mình đã đưa ra khi đăng câu hỏi, nhưng nói chung, tôi đang tìm cách đảm bảo ứng dụng của mình (một công cụ trò chơi đơn giản mà tôi ' m làm) nhận được một số sự chú ý của lịch trình càng thường xuyên càng tốt - lý tưởng trong mọi lát thời gian. Tôi muốn giữ nó trơn tru nhất có thể, và có ngân sách 16,67ms thời gian xử lý cho mỗi khung hình với tốc độ làm tươi màn hình 60Hz. Một thử nghiệm đơn giản đã chứng minh rằng thread của tôi có thể được ưu tiên hơn 10ms. Tôi đoán tôi sẽ phải sống với thực tế một khung có thể được bỏ qua nếu tôi muốn được tốt đẹp cho hệ điều hành. –

+0

Đối với "PPL" và "AAL" - chúng trông rất thú vị, cảm ơn đã cho họ thấy. –

+0

Nếu bạn thực sự muốn lấy muck với các ưu tiên thì hãy xem AvSetMmThreadCharacteristics và AvSetMmThreadPriority. Chúng phù hợp với kịch bản của bạn trong việc cung cấp đảm bảo. Một lần nữa tôi khuyên bạn nên xem xét các API. Tôi cũng viết một trò chơi để chứng minh làm thế nào điều này có thể được thực hiện với họ. – Rick

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