In multi-threaded programs, we often encounter this situation, the main thread starts loading some parameters into the memory of an object or data structure, the object or data structure as parameters passed into each sub-thread, in order to avoid the copying and copy of the object, often passed pointer, sub-thread start, business logic processing, You need to get Value,value = M_pparam->get (key) in Hashtable based on the key value, as shown in the code below
//run the required parameters with the Hashtable save programHashtable<key, value>Hashparam;voidLoadparam (Hashtable<key, Value> &Hashparam) { //Load Parameters return;}//simulating threading Classesclassthreadx{ Public: ThreadX (Hashtable<key, value> *pparam): M_pparam (Pparam) {...}
T * GET (int key)
{
return M_pparam->get (key);
} /*other Members*/Private: Hashtable<key, value> *M_pparam; /*other Members*/};
The main thread will construct the Hashtable incoming child thread, where the sub-thread to Hashtable operation is read-only operation, so that other threads do not modify the Hashtable data, so the operation here is not locked. As the requirements change, the data in Hashtable now needs to support dynamic refresh, that is, the previous parameters may be changed (parameters in the database, configuration file information, etc.), in the program run by sending a semaphore, the main thread to reload the parameters. The usual practice is that the M_hashparam + Mutual exclusion lock for encapsulation, the structure should be synparam, lock in operation: Main line loads load parameters, lock () read parameters to memory, M_hashparam->put (key, value), Unlock (), The same approach is handled when the parameters are reloaded. The sub-thread also saves the encapsulated structure of the Synparam pointer, M_psynparam, and in operation, the lock protection. This allows the main thread to refresh the parameters when the program receives the semaphore for the parameter refresh, while the child threads are reading the latest data. Note that when M_synparam->get (key) is in a child thread, it is also necessary to lock the data so that the reading is correct, and the principle is equivalent to a thread that writes multiple threads to read the classic question. In the program, the frequency of parameter refresh is much lower than the sub-thread in the parameter structure of the read, although the parameters can be guaranteed to read the latest, but the cost of lock is too high, will affect the efficiency of the program.
Now consider another way that the main thread still loads the data into memory, assuming that it is loaded into hashparam_a, set phashparam = &hashparam_a, create a child thread in the main thread, pass Phashparam as a parameter to the child thread, note that The address of the Phashparam is saved in the child thread, M_pphash = &phashparam, that is, Pphash = & (&m_hashparam), in the child thread, get the key value operation represented as: value = (*pphash) ->get (key); There are also read-only operations, and no locks are added:
voidLoadparam (Hashtable<key, Value> &Hashparam) { //Load Parameters return;}classthreadx{ Public: ThreadX (Hashtable<key, value> *pparam): M_pparam (&pparam) {...} /*other Members*/T*Get(intkey) {Value= (*m_ppparam)Get(key); }Private: Hashtable<key, value> **m_ppparam;//Note that this is a level two pointer . /*other Members*/};hashtable<key, value>Hashparam_a;loadparam (hashparam_a); Hashtable<key, value> * pparam = &Hashparam_a; THREADX THD (pparam);
When the parameter is refreshed, the main line loads loads the memory into another same struct m_hashparamb, which changes the value of the seasonal Pparam = &hashparamb,pparam, and m_ppparam in the child thread points to phash, so * The value of the Pphash also changed, actually pointing to Hashparamb, the new memory structure:
Hashtable<key, value> hashparam_b;loadparam (hashparam_b); Hashtable<key, value> * pparam = & Hashparam_b;
Note that the reason Phash=&hashparam_b is not locked is because on a 32-bit platform, here is an atomic operation, so you can guarantee that the child thread value = (*m_ppparam)->get (key); The most recent parameter value is obtained. In the case of a 64-bit platform, pointer assignment to Pparam = &hashparam_b may be broken down into 2 instructions, which may result in a child thread getting value, when referring to *m_ppparam, *ppparam Point to an address that represents an error!
Use a level two pointer to perform a refresh operation in multiple threads