C에서 스레드 풀 만들기++

C에서 스레드 풀 만들기++

2022-06-04 last update

5 minutes reading C++
스레드 탱크는 하나의 스레드로 그 중에서 모든 스레드는 실행해야 할 임무가 있다.따라서 서로 다른 라인은 서로 다른 유형의 임무를 수행한다.따라서 모든 노선에는 특정한 임무가 있다.임무는 기본적으로 일종의 기능이다.유사한 기능은 특정 라인에서 완성된다.서로 다른 유사 함수 집합은 다른 라인에서 완성되며, 이에 따라 유추된다.비록 실행 루틴은 최고급 함수를 실행하지만, 정의에 따라thread 클래스의 대상의 실례화입니다.서로 다른 스레드에는 서로 다른 매개 변수가 있기 때문에 특정한 스레드는 유사한 함수를 처리해야 한다.
C++에서 이 스레드 풀을 관리해야 합니다.C++는 스레드 풀을 만드는 데 사용할 라이브러리가 없고 관리됩니다.이것은 아마도 스레드 탱크를 만드는 방법이 다르기 때문일 것이다.따라서 C++ 프로그래머는 필요에 따라 스레드 풀을 만들어야 합니다.
무엇이 선입니까?스레드는thread류에서 실례화된 대상입니다.정상적인 실례화에서 루틴 구조 함수의 첫 번째 매개 변수는 최고급 함수의 이름이다.루틴 구조 함수의 나머지 매개 변수는 함수의 매개 변수이다.루틴이 실례화되면 함수가 실행되기 시작합니다.C++main() 함수는 최상위 함수입니다.이 전역 범위의 다른 함수는 최고급 함수입니다.main () 함수는 다른 라인처럼 정식으로 설명해야 하는 라인이 아닙니다.다음 계획을 고려하십시오.
#include 
#include 
using namespace std;

void func() {
cout << "code for first output" << endl;
cout << "code for second output" << endl;
}

int main()
{
thread thr(func);
thr.join();
/* other statements */

return 0;
}
출력:
code for first output
code for second output
thread 클래스가 있는 루틴 라이브러리가 포함되어 있음을 주의하십시오.func () 는 최고급 함수입니다.main () 함수의 첫 번째 문장은 스레드thr의 실례화에서 사용됩니다.main () 의 다음 문장은join 문장입니다.이것은 라인thr를main () 함수 라인체의 인코딩 위치에 연결합니다.이 문장이 없으면, 주 함수는 완성될 때까지 실행될 수 있고, 스레드 함수는 완성되지 않을 것입니다.이것은 번거롭다는 것을 의미한다.
다음과 같은 명령을 사용하여 g++ 컴파일러에서 C++20 루틴 프로그램을 실행해야 합니다.
g++ -std=c++2a temp.cpp -lpthread -o temp
본고는 C++에서 스레드 탱크를 만들고 관리하는 방법을 소개했다.

문장 내용






  • 스레드 풀 예제 요구 사항


    이 예시적인 스레드 탱크의 요구는 매우 간단하다. 세 개의 스레드와 하나의 메인 스레드가 있다.라인은 주 라인에 속한다.각 종속 스레드는 대기열 데이터 구조를 사용합니다.그래서 세 개의 대기열이 있습니다.프로그램에 대기열 라이브러리와 루틴 라이브러리가 포함되어야 합니다.
    모든 대기열은 여러 개의 함수를 호출할 수 있지만, 같은 최고급 함수를 가지고 있다.즉, 대기열의 모든 요소는 특정한 최고급 함수에 대한 함수 호출이다.따라서 세 가지 다른 최고급 함수가 있는데 그것이 바로 각 라인마다 최고급 함수이다.함수 이름은 fn1, fn2, fn3입니다.
    각 대기열의 함수 호출은 매개 변수에서만 다르다.간단하게 보기 위해서, 이 프로그램의 예시에 대해 함수 호출은 매개 변수가 없을 것이다.사실상 이 예에서 모든 대기열의 값은 같은 정수이다. 1은 모든qu1원소의 값이다.2는 모든q2원소의 값으로 한다.과 3은 모든 q3 원소의 값입니다.
    대기열은 first\u in-first\u out 구조입니다.따라서 첫 번째 대기열에 들어간 호출(번호)은 첫 번째로 떠났다.호출 (번호) 이 떠날 때, 상응하는 함수와 라인을 실행합니다.
    main () 함수는 세 개의 대기열 중 하나에 해당하는 함수 호출을 제공하여 해당하는 라인에 호출을 제공한다.
    주 루틴은 모든 대기열에 호출이 있는지 확인하고, 호출이 있으면 그 루틴을 통해 해당하는 함수를 호출합니다.이 프로그램의 예시에서 대기열에 라인이 없을 때 프로그램이 끝납니다.
    최상위 수준의 기능은 다음과 같습니다.
    void fn1() {
    cout << "fn1" << endl;
    }
    
    void fn2() {
    cout << "fn2" << endl;
    }
    
    void fn3() {
    cout << "fn3" << endl;
    }
    상응하는 나사는thr1,thr2,thr3이다.주 라인은 자신의 주 기능을 가지고 있다.여기에는 함수마다 문장이 하나밖에 없다.함수 fn1 () 의 출력은 "fn1"입니다.함수 fn2 () 의 출력은 "fn2"입니다.함수 fn3 () 의 출력은 "fn3"입니다.
    본고의 말미에 독자는 본고의 모든 코드 단락을 한데 조합하여 하나의 스레드 탱크 프로그램을 형성할 수 있다.

    전역 변수


    전역 변수를 포함하는 프로그램의 상단은 다음과 같습니다.
    #include 
    #include 
    #include 
    using namespace std;
    
    queue qu1;
    queue qu2;
    queue qu3;
    
    thread thr1;
    thread thr2;
    thread thr3;
    대기열과 스레드 변수는 전역 변수입니다.그것들은 이미 초기화나 성명이 없는 상황에서 성명되었다.그 다음에 프로그램에서 세 개의 하급 상단 함수이어야 한다. 위와 같다.
    cout 대상은iostream 라이브러리를 포함합니다.스레드 라이브러리는 스레드에 포함되어 있습니다.스레드의 이름은thr1,thr2,thr3입니다.대기열 라이브러리가 대기열에 포함되어 있습니다.대기열의 이름은qu1,qu2,qu3입니다.q1 대응thr1;q2는thr2에 대응하고,q3는thr3에 대응한다.대기열은 벡터와 유사하지만 FIFO(first\u in-first\u out)에 적용됩니다.

    주 스레드 함수


    다음 세 개의 하위 맨 위 함수는 프로그램의 주 함수입니다.예:
    void masterFn() {
    work:
    if (qu1.size() > 0) thr1 = thread(fn1);
    if (qu2.size() > 0) thr2 = thread(fn2);
    if (qu3.size() > 0) thr3 = thread(fn3);
    
    if (qu1.size() > 0) {
    qu1.pop();
    thr1.join();
    }
    if (qu2.size() > 0) {
    qu2.pop();
    thr2.join();
    }
    if (qu3.size() > 0) {
    qu3.pop();
    thr3.join();
    }
    
    if (qu1.size() == 0 && qu1.size() == 0 && qu1.size() == 0)
    return;
    goto work;
    }
    goto 순환은 함수를 포함하는 모든 코드를 포함합니다.모든 대기열이 비어 있을 때, 함수는void를 되돌려주고, 문장 "return;"을 사용합니다.
    goto 순환 중의 첫 번째 코드 세그먼트는 세 개의 문장이 있습니다. 각 대기열과 대응하는 라인마다 한 개의 문장이 있습니다.여기서 대기열이 비어 있지 않으면 그 라인을 실행합니다.
    다음 코드 세그먼트는 세 개의if구조로 구성되어 있으며, 각각if구조는 하나의 종속 라인에 대응한다.각각if구조는 두 개의 문장이 있다.첫 번째 문장은 첫 번째 코드 세그먼트에서 발생할 수 있는 번호를 삭제합니다.다음은join문장으로 상응하는 스레드가 완성될 때까지 작동하도록 확보합니다.
    goto 순환의 마지막 문장 끝 함수, 모든 대기열이 비어 있으면 순환을 종료합니다.

    Main () 함수


    프로그램의 주 스레드 함수 다음에는 main () 함수여야 합니다.
    qu1.push(1);
    qu1.push(1);
    qu1.push(1);
    
    qu2.push(2);
    qu2.push(2);
    
    qu3.push(3);
    
    thread masterThr(masterFn);
    cout << "Program has started:" << endl;
    masterThr.join();
    cout << "Program has ended." << endl;
    main () 함수는 호출된 숫자를 대기열에 넣는 것을 책임집니다.Qu1에는 세 개의 값이 있습니다. 1;q2는 두 개의 값이 있고, q3는 하나의 값이 있다.main () 함수는 주 루틴을 시작하여 주체에 연결합니다.작성자 컴퓨터의 출력은 다음과 같습니다.
    Program has started:
    fn2
    fn3
    fn1
    fn1
    fn2
    fn1
    Program has ended.
    디스플레이 라인의 불규칙한 병행 동작을 출력합니다.main () 함수가 주 스레드에 들어가기 전에 프로그램이 시작되었습니다.주 루틴은thr1은fn1(),thr2는fn2(),thr3는fn3()를 차례로 호출합니다.그러나 상응하는 출력은'fn2','fn3','fn1'에서 시작한다.최초의 주문은 문제가 없습니다.이것이 바로 병행하여 불규칙하게 운행하는 방식이다.나머지 출력 문자열은 함수를 호출할 때 표시됩니다.
    주 기능체가 주 라인에 가입한 후, 그것은 주 라인이 완성되기를 기다린다.주 라인을 완성하려면 모든 대기열이 비어 있어야 합니다.모든 대기열 값은 해당 라인의 실행에 대응합니다.따라서 모든 대기열을 공백으로 만들려면 그 라인은 반드시 이 횟수를 실행해야 한다.대기열에 요소가 있습니다.
    주 루틴과 그 루틴이 실행되고 끝날 때, 주 함수는 계속 실행됩니다.프로그램이 종료되었습니다.

    결론


    스레드 탱크는 하나의 스레드이다.모든 노선은 자신의 임무를 집행하는 것을 책임진다.임무는 기능이다.이론적으로 말하자면, 임무는 항상 올 것이다.위의 예에서 보듯이 그것들은 결코 진정으로 끝나지 않았다.일부 실제 예시에서 데이터는 라인 사이에서 공유된다.데이터를 공유하기 위해 프로그래머는 조건 변수, 비동기 함수, 약속과 미래를 이해해야 한다.이것은 또 다른 시간의 토론이다.