thread is determined during compile or runtime?

i just ask my self:when i make pool of threads in code
then i compile the code ,
does the compiled code have a copy for each thread?

and if i use macro function , and pass it to the threads,
is this macro expanded during compile time"what i think" or during runtime,
and if it is in compile time why this following code need mutex:

#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();
}

here the lock_guard make cout critical section,although only the main thread will be the thread posting to io_service
then the threads running tasks will work on already made queue of already made lamda functions >>>>which make me think there is no need for mutex?
is this thinking right?

here i will simulate the macro expansion during compilation:

#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();
}  

and then the program will be in the following order:
1- main thread :make io_service instance
2- main thread :make mutex instance
3- main thread :make for loop 20 times ,each time the main thread post a task"the lambda function" which is defined in the book having this code as adding this function object to an internal queue in io_service so
my question is :does the main thread add 20 lambda function objects to the queue and in this case each one would have certain value of i
and then when the new 4 threads start work,he gives them thread function "run" which according to same book remove the function objects one by one and execute them one by one
in this case:
thread 1:removes lambda 1 and execute it with its own code as being separate instance with unique i
thread 2:removes lambda 2 and execute it with its own code as being separate instance with unique i
thread 3:removes lambda 3 and execute it with its own code as being separate instance with unique i
thread 4:removes lambda 4 and execute it with its own code as being separate instance with unique i
then thread one againget lambda 5
this is based on my understanding that the queue has 20 function objects as lambda functions"may be wrapped in somesort of wrapper" and thus each thread will take separate object and for this reason need no mutex"20 internal assembly codes after compilation"

but if the tasks in queue are just references to the same single code"but when it execute the for loop" ,then it will need mutex to prevent 2 threads accessing the critical code at same time
which scenario is the present here by code signs?


Macros are always expanded at compile time but the compiler has only very rudimentary knowledge of threads (mostly regarding being able to say that certain variables are thread local).

Code is only going to exist once in either the on-disk image or in-memory copy that actually gets run.

Locking the mutex in PRINT_ARGS ensures that each operation's message is printed in its entirety without getting interrupted by another thread. (Otherwise you might have a operation start to print its message, get interrupted by another operation on a different thread which does print its message and then the remainder of the first operation's message gets printed).

链接地址: http://www.djcxy.com/p/78934.html

上一篇: 在C ++中,什么是虚拟基类?

下一篇: 线程在编译或运行时确定?