문제

나는 그것을 의심 할 수 있습 portably 지만,어떤 해결책이 있습니까?나는 그것을 할 수 있을 작성하여 다른 스택하고 재설정 SP,BP,IP 에 기능 항목 및 수확량 저장 IP 과 복원 SP+BP.소멸자 및 예외 안전 까다로워 보이지만 해결할 수 있습니다.

되었는가?불가능한가?

도움이 되었습니까?

해결책

할 수 있습니다 문제없이. 호출 스택을 힙에 새로 할당 된 스택으로 옮기기위한 작은 어셈블리 코드 만 있으면됩니다.

나는 할 것이다 를보세요 부스트 :: 코 루틴 도서관.

당신이 조심해야 할 것은 스택 오버플로입니다. 대부분의 운영 체제에서 오버플레이션에서 스택은 가상 메모리 페이지가 매핑되지 않기 때문에 segfault가 발생합니다. 그러나 힙에 스택을 할당하면 보장이 없습니다. 그냥 명심하십시오.

다른 팁

POSIX에서는 makecontext ()/swapcontext () 루틴을 사용하여 실행 컨텍스트를 포괄적으로 전환 할 수 있습니다. Windows에서는 섬유 API를 사용할 수 있습니다. 그렇지 않으면 필요한 것은 기계 컨텍스트를 전환하는 약간의 접착제 어셈블리 코드입니다. ASM (AMD64의 경우)과 SwapContext ()가있는 코 루틴을 구현했습니다. 둘 다서도 어렵지 않습니다.

후손을 위해

Dmitry Vyukov 's 놀라운 웹 사이트 C ++에서 시뮬레이션 된 코 루틴에 UCONTEXT 및 SETJUMP를 사용하여 영리한 트릭이 있습니다.

또한 Oliver Kowalke의 맥락 도서관도있었습니다 최근에 받아 들여졌습니다 Boost는 곧 x86_64에서 작동하는 Boost.coroutine의 업데이트 된 버전을 볼 수 있기를 바랍니다.

Coroutine을 구현하는 쉬운 방법은 없습니다. Coroutine 자체는 C/C ++의 스택 추상화가 스레드와 마찬가지로 사용되지 않기 때문입니다. 따라서 지원을 위해 언어 수준 변경 없이는 지원할 수 없습니다.

현재 (C ++ 11), 기존의 모든 C ++ Coroutine 구현은 모두 어셈블리 레벨 해킹을 기반으로하며 플랫폼을 통해 안전하고 신뢰할 수있는 교차로가 어렵습니다. 신뢰할 수 있으려면 표준이어야하며 해킹보다는 컴파일러가 처리해야합니다.

거기에 표준 제안 -N3708 이것을 위해. 관심이 있으시면 확인하십시오.

가능한 경우 코 루틴보다 반복자로 더 나을 수 있습니다. 그렇게하면 계속 전화 할 수 있습니다 next() 다음 값을 얻으려면 상태를 로컬 변수 대신 멤버 변수로 유지할 수 있습니다.

일을 더욱 관리 할 수있게 할 수 있습니다. 다른 C ++ 개발자는 코 루틴을 즉시 이해하지 못하는 반면 반복자에 더 익숙 할 수 있습니다.

를 알고 싶은 사람들은 그들이 어떻게 활용할 수 있습 하에서 휴대용 방식에서는 C++당신을 기다려야 할 것이를 위한 C++17 야기이다(아래 참조)!표준 위원회는 작업에 기능 표시 N3722paper.요약하면 현재 초안의 종이 대신,비동기와 기다리고 있는 키워드는 것이 다시 시작 가능,그리고 기다리고 있습니다.

을 살펴 실험적인 구현을 Visual Studio 에서 2015 년을 재생하는 Microsoft 의 실험적인 구현합니다.그것처럼 보이지 않는 그 소리는 아직 구현.

거기에 좋은 이야기에서 Cppcon 하는 부정적인 오버헤드 추출 개략을 사용하는의 이득 하는 C++에서 어떻게 영향을 미치는 단순성과 성능의 코드입니다.

현재 우리는 여전히 사용하는 라이브러리 구현,하지만 가까운 미래에 우리가 하로 core C++기능입니다.

업데이트:처럼 보이는 coroutine 구현할 예정을 위한 C++20,그러나이었다로 출시된 기술 사양으로 C++17(p0057r2).Visual C++,그 소리와 gcc 수신을 거부할 수 있을 사용하여 컴파일 시기이다.

하다 코 루틴 코 루틴 시퀀싱을위한 휴대용 C ++ 라이브러리 당신을 올바른 방향으로 가리십니까? 시간의 시험을 지속시킨 우아한 솔루션처럼 보입니다 ..... 9 살입니다!

DOC 폴더에는 논문의 PDF가 있으며 Keld Helsgaun의 Coroutine 시퀀싱을위한 휴대용 C ++ 라이브러리가 라이브러리를 설명하고이를 사용하는 짧은 예제를 제공합니다.

업데이트] 저는 실제로 직접 사용하고 있습니다. 호기심이 나에게 더 나아졌다. 그래서 나는이 솔루션을 살펴 보았고, 내가 한동안 작업했던 문제에 적합하다는 것을 알았다!

나는 C ++에 많은 본격적인 깨끗한 구현이 있다고 생각하지 않습니다. 내가 좋아하는 시도는 하나입니다 Adam Dunkels의 프로토 스레드 도서관.

또한보십시오 Protothreads : 메모리 제약 임베디드 시스템의 이벤트 중심 프로그래밍 단순화 ACM 디지털 라이브러리 및 Wikipedia Topic의 토론에서 프로토 스레드,

새로운 도서관, boost.context, 오늘 코 루틴 구현을위한 휴대용 기능으로 오늘 출시되었습니다.

이것은 오래된 스레드이지만, os 의존적이지 않은 Duff의 장치를 사용하여 해킹을 제안하고 싶습니다 (내가 기억하는 한).

C Coroutines Duff의 장치를 사용합니다

예를 들어, 여기에 포크/스레드 대신 코 루틴을 사용하도록 수정 한 텔넷 라이브러리가 있습니다.텔넷 CLI 라이브러리를 사용하여 코 루틴을 사용합니다

그리고 C99 이전의 표준 C는 본질적으로 C ++의 실제 하위 집합이기 때문에 C ++에서도 잘 작동합니다.

(Cringe) 매크로를 기반으로하지만 다음 사이트는 사용하기 쉬운 발전기 구현을 제공합니다. http://www.codeproject.com/kb/cpp/cpp_generator.aspx

구현을 생각해 냈습니다 ASM없이 암호. 아이디어는 시스템 스레드 생성 기능을 사용하여 스택 및 컨텍스트를 초기화하고 SetJMP/LongJMP를 사용하여 컨텍스트를 전환하는 것입니다. 그러나 휴대용이 아닙니다 까다로운 pthread 버전 관심이 있다면.

https://github.com/tonbit/coroutine C ++ 11 단일 .h 비대칭 코 루틴 구현 이력서/수율/차단 프리미티브 및 채널 모델을 지원합니다. Linux/Windows/MacOS에서 실행되는 부스트에 따라 UContext/Fiber를 통해 구현됩니다. C ++에서 코 루틴 구현을 배우는 것이 좋은 출발점입니다.

내 구현을 확인하십시오. ASM 해킹 지점을 보여주고 간단합니다.

https://github.com/user1095108/generic/blob/master/coroutine.hpp

대신 스레드 사용을 항상 고려해야합니다. 특히 현대 하드웨어에서. 공동 경로에서 논리적으로 분리 될 수있는 작업이있는 경우 스레드를 사용하면 별도의 실행 장치 (프로세서 코어)에 의해 작업이 실제로 동시에 수행 될 수 있음을 의미합니다.

그러나 아마도 당신은 아마도 당신이 이미 쓰여지고 테스트 한 잘 테스트 된 알고리즘을 가지고 있거나, 그런 식으로 작성된 코드를 포팅하고 있기 때문에 아마도 코 루틴을 사용하고 싶을 것입니다.

Windows에서 일하는 경우 섬유. 섬유는 OS에서 지원하는 코 루틴과 같은 프레임 워크를 제공합니다.

다른 OS에 익숙하지 않습니다. 대안을 추천합니다.

wvcont 의 일부입니다 WVStream 이는 소위 반 코 루틴을 구현합니다. 이것들은 풀 온 코 루틴보다 다루기가 조금 더 쉽습니다.

전체 코 루틴을 지원하는보다 유연한 WVTASK를 사용하여 구현되었습니다. 같은 라이브러리에서 찾을 수 있습니다.

최소한 Win32 및 Linux 및 아마도 다른 UNIX 시스템에서 작동합니다.

C ++ 11과 스레드를 사용하여 직접 코 루틴을 구현하려고했습니다.

#include <iostream>
#include <thread>

class InterruptedException : public std::exception {
};

class AsyncThread {
public:
    AsyncThread() {
        std::unique_lock<std::mutex> lock(mutex);
        thread.reset(new std::thread(std::bind(&AsyncThread::run, this)));
        conditionVar.wait(lock); // wait for the thread to start
    }
    ~AsyncThread() {
        {
            std::lock_guard<std::mutex> _(mutex);
            quit = true;
        }
        conditionVar.notify_all();
        thread->join();
    }
    void run() {
        try {
            yield();
            for (int i = 0; i < 7; ++i) {
                std::cout << i << std::endl;
                yield();
            }
        } catch (InterruptedException& e) {
            return;
        }
        std::lock_guard<std::mutex> lock(mutex);
        quit = true;
        conditionVar.notify_all();
    }
    void yield() {
        std::unique_lock<std::mutex> lock(mutex);
        conditionVar.notify_all();
        conditionVar.wait(lock);
        if (quit) {
            throw InterruptedException();
        }
    }
    void step() {
        std::unique_lock<std::mutex> lock(mutex);
        if (!quit) {
            conditionVar.notify_all();
            conditionVar.wait(lock);
        }
    }
private:
    std::unique_ptr<std::thread> thread;
    std::condition_variable conditionVar;
    std::mutex mutex;
    bool quit = false;
};

int main() {
    AsyncThread asyncThread;
    for (int i = 0; i < 3; ++i) {
        std::cout << "main: " << i << std::endl;
        asyncThread.step();
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top