난 그냥 내 자신에게 물어 : 코드에 스레드 풀을 만들 때
코드를 컴파일
컴파일 된 코드가 각 스레드에 대한 복사본을 가지고 있습니까? 내가 매크로 기능을 사용하고
컴파일 시간 동안 확장이 매크로입니다, 스레드에 전달하면스레드는 컴파일 또는 런타임 중에 결정됩니까?
가와 "내가 무슨 생각"또는시 런타임,
을 그리고 컴파일시에있는 경우 왜 다음 코드 필요 뮤텍스 : 오직 주 스레드는 이미 람다 함수를 만들어의 작업을 이미 만든 큐에 작동 실행 다음 스레드를
을 io_service하는 스레드를 게시 될 것입니다하지만 여기
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
#include <iostream>
namespace asio = boost::asio;
#define PRINT_ARGS(msg) do {\
boost::lock_guard<boost::mutex> lg(mtx); \
std::cout << '[' << boost::this_thread::get_id() \
<< "] " << msg << std::endl; \
} while (0)
int main() {
asio::io_service service;
boost::mutex mtx;
for (int i = 0; i < 20; ++i) {
service.post([i, &mtx]() {
PRINT_ARGS("Handler[" << i << "]");
boost::this_thread::sleep(
boost::posix_time::seconds(1));
});
}
boost::thread_group pool;
for (int i = 0; i < 4; ++i) {
pool.create_thread([&service]() { service.run(); });
}
pool.join_all();
}
가 lock_guard가, cout을 임계 영역을 >>> > 뮤텍스가 필요 없다고 생각하게 만들었습니까?
이 생각인가요? 여기
내가 컴파일 중에 매크로 확장을 시뮬레이션합니다
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
#include <iostream>
namespace asio = boost::asio;
#define PRINT_ARGS(msg) do {\
boost::lock_guard<boost::mutex> lg(mtx); \
std::cout << '[' << boost::this_thread::get_id() \
<< "] " << msg << std::endl; \
} while (0)
int main() {
asio::io_service service;
boost::mutex mtx;
for (int i = 0; i < 20; ++i) {
service.post([i, &mtx]() {
//PRINT_ARGS("Handler[" << i << "]");//>>>>>this will be
do {\\
boost::lock_guard<boost::mutex> lg(mtx); \\
std::cout << '[' << boost::this_thread::get_id() \\
<< "] " << "Handler[" << i << "]" << std::endl; \\
} while (0)
boost::this_thread::sleep(
boost::posix_time::seconds(1));
});
}
boost::thread_group pool;
for (int i = 0; i < 4; ++i) {
pool.create_thread([&service]() { service.run(); });
}
pool.join_all();
}
를 다음 프로그램은 다음과 같은 순서에있을 것입니다 :
1 주 스레드 : io_service 예를
2 주 스레드를합니다 수 있도록 뮤텍스 인스턴스
3 개의 메인 스레드 : 메인 스레드가이 코드를 가지고있는 책에 정의 된 "람다 함수"를 io_service의 내부 큐에 추가 할 때마다 루프를 20 번 반복한다.
내 질문은 입니다. : 주 스레드가 큐에 20 개의 람다 함수 객체를 추가합니까?이 경우 각각의 값은 i
이고 새로운 4 개의 스레드가 작업을 시작하면 동일한 책에 따라 스레드 기능 "실행"을 제공합니다 함수 하나씩 객체를 제거하고이 경우 하나
하나씩 실행한다
쓰레드 (1) : 삭제 (λ1) 및 고유에 개별 인스턴스로서 자신의 코드를 실행하는 I
실 2 : 삭제 (λ2) 및 자체 코드를 고유 한 i와 별도의 인스턴스로 실행합니다.
스레드 3 : 람다 3을 제거하고 고유 코드를 사용하여 고유 한 코드로 실행합니다.
스레드 4 : 람다 제거 4 고유 한 코드로 별도의 인스턴스로 실행하십시오
다음은 스레드 1 againget lambda 5
이것은 큐에 람다 함수로 20 개의 함수 객체가 있습니다. "wrapper의 somesort로 래핑 될 수 있습니다" 따라서 각 스레드는 별도의 객체를 가져 오며 이런 이유로 컴파일 후에 "20 개의 내부 어셈블리 코드"가 필요하지 않습니다.
그러나 큐의 작업이 " , 동시에 2 개의 스레드가 중요한 코드에 동시에 액세스하는 것을 막기 위해 뮤텍스가 필요합니다.
어떤 시나리오가 현재 코드 기호로 표시됩니까?
나는 매크로 이름을 확장하기 위해 코드를 편집했는데 뮤텍스가 여전히 대기열에있는 람다 함수 안에 있고 스레드에 주어진 실행 함수가 람다 함수가 아니라는 것을 알았습니다 ..... 그렇다면 왜 우리는 1 개의 람다를 대표하는 각각 20 개의 작업이 있다면 뮤텍스가 필요합니다 –
뮤텍스가 작업이 아니라 여기에 있다고 생각합니까? –
예, 뮤텍스는 출력이 혼합되지 않도록 유지합니다. 람다는 주변 컨텍스트로부터 뮤텍스를 캡쳐하고 있으므로 실제로 뮤텍스가 하나만 있다는 것을 기억하십시오 (많은 참조가 있습니다). – SoronelHaetir