run_study 1 > 1.out& run_study 2 > 2.out; wait
One could of course argue that the bash ampersand operator and the ``wait'' primitive are in fact synchronization primitives. If so, then consider that this script could be run manually in two separate command windows, so that the only synchronization would be supplied by the user himself or herself.
Quick Quiz .2:
What problems could occur if the variable counter were
incremented without the protection of mutex?
Answer:
On CPUs with load-store architectures, incrementing counter
might compile into something like the following:
LOAD counter,r0 INC r0 STORE r0,counter |
On such machines, two threads might simultaneously load the value of counter, each increment it, and each store the result. The new value of counter will then only be one greater than before, despite two threads each incrementing it.
Quick Quiz .3:
How could you work around the lack of a per-thread-variable
API on systems that do not provide it?
Answer:
One approach would be to create an array indexed by
smp_thread_id(), and another would be to use a hash
table to map from smp_thread_id() to an array
index -- which is in fact what this
set of APIs does in pthread environments.
Another approach would be for the parent to allocate a structure containing fields for each desired per-thread variable, then pass this to the child during thread creation. However, this approach can impose large software-engineering costs in large systems. To see this, imagine if all global variables in a large system had to be declared in a single file, regardless of whether or not they were C static variables!
Paul E. McKenney 2011-12-16