📄 shared.html
字号:
<a href="#item_cond_wait"><code>cond_wait</code></a> blocked on is relocked after the <a href="#item_cond_wait"><code>cond_wait</code></a> is satisfied. If
there are multiple threads <a href="#item_cond_wait"><code>cond_wait</code></a>ing on the same variable, all but one
will reblock waiting to reacquire the lock on the variable. (So if you're only
using <a href="#item_cond_wait"><code>cond_wait</code></a> for synchronisation, give up the lock as soon as possible).
The two actions of unlocking the variable and entering the blocked wait state
are atomic, the two actions of exiting from the blocked wait state and
relocking the variable are not.</p>
</dd>
<dd>
<p>In its second form, <a href="#item_cond_wait"><code>cond_wait</code></a> takes a shared, <strong>unlocked</strong> variable followed
by a shared, <strong>locked</strong> variable. The second variable is unlocked and thread
execution suspended until another thread signals the first variable.</p>
</dd>
<dd>
<p>It is important to note that the variable can be notified even if no thread
<a href="#item_cond_signal"><code>cond_signal</code></a> or <a href="#item_cond_broadcast"><code>cond_broadcast</code></a> on the variable. It is therefore
important to check the value of the variable and go back to waiting if the
requirement is not fulfilled. For example, to pause until a shared counter
drops to zero:</p>
</dd>
<dd>
<pre>
<span class="operator">{</span> <span class="keyword">lock</span><span class="operator">(</span><span class="variable">$counter</span><span class="operator">);</span> <span class="variable">cond_wait</span><span class="operator">(</span><span class="variable">$count</span><span class="operator">)</span> <span class="keyword">until</span> <span class="variable">$counter</span> <span class="operator">==</span> <span class="number">0</span><span class="operator">;</span> <span class="operator">}</span>
</pre>
</dd>
</li>
<dt><strong><a name="item_cond_timedwait_variable_2c_abs_timeout">cond_timedwait VARIABLE, ABS_TIMEOUT</a></strong>
<dt><strong><a name="item_cond_timedwait_condvar_2c_abs_timeout_2c_lockvar">cond_timedwait CONDVAR, ABS_TIMEOUT, LOCKVAR</a></strong>
<dd>
<p>In its two-argument form, <code>cond_timedwait</code> takes a <strong>locked</strong> variable and an
absolute timeout as parameters, unlocks the variable, and blocks until the
timeout is reached or another thread signals the variable. A false value is
returned if the timeout is reached, and a true value otherwise. In either
case, the variable is re-locked upon return.</p>
</dd>
<dd>
<p>Like <a href="#item_cond_wait"><code>cond_wait</code></a>, this function may take a shared, <strong>locked</strong> variable as an
additional parameter; in this case the first parameter is an <strong>unlocked</strong>
condition variable protected by a distinct lock variable.</p>
</dd>
<dd>
<p>Again like <a href="#item_cond_wait"><code>cond_wait</code></a>, waking up and reacquiring the lock are not atomic,
and you should always check your desired condition after this function
returns. Since the timeout is an absolute value, however, it does not have to
be recalculated with each pass:</p>
</dd>
<dd>
<pre>
<span class="keyword">lock</span><span class="operator">(</span><span class="variable">$var</span><span class="operator">);</span>
<span class="keyword">my</span> <span class="variable">$abs</span> <span class="operator">=</span> <span class="keyword">time</span><span class="operator">()</span> <span class="operator">+</span> <span class="number">15</span><span class="operator">;</span>
<span class="keyword">until</span> <span class="operator">(</span><span class="variable">$ok</span> <span class="operator">=</span> <span class="variable">desired_condition</span><span class="operator">(</span><span class="variable">$var</span><span class="operator">))</span> <span class="operator">{</span>
<span class="keyword">last</span> <span class="keyword">if</span> <span class="operator">!</span><span class="variable">cond_timedwait</span><span class="operator">(</span><span class="variable">$var</span><span class="operator">,</span> <span class="variable">$abs</span><span class="operator">);</span>
<span class="operator">}</span>
<span class="comment"># we got it if $ok, otherwise we timed out!</span>
</pre>
</dd>
</li>
<dt><strong><a name="item_cond_signal">cond_signal VARIABLE</a></strong>
<dd>
<p>The <a href="#item_cond_signal"><code>cond_signal</code></a> function takes a <strong>locked</strong> variable as a parameter and
unblocks one thread that's <a href="#item_cond_wait"><code>cond_wait</code></a>ing on that variable. If more than one
thread is blocked in a <a href="#item_cond_wait"><code>cond_wait</code></a> on that variable, only one (and which one
is indeterminate) will be unblocked.</p>
</dd>
<dd>
<p>If there are no threads blocked in a <a href="#item_cond_wait"><code>cond_wait</code></a> on the variable, the signal
is discarded. By always locking before signaling, you can (with care), avoid
signaling before another thread has entered cond_wait().</p>
</dd>
<dd>
<p><a href="#item_cond_signal"><code>cond_signal</code></a> will normally generate a warning if you attempt to use it on an
unlocked variable. On the rare occasions where doing this may be sensible, you
can skip the warning with:</p>
</dd>
<dd>
<pre>
<span class="operator">{</span> <span class="keyword">no</span> <span class="variable">warnings</span> <span class="string">'threads'</span><span class="operator">;</span> <span class="variable">cond_signal</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">);</span> <span class="operator">}</span>
</pre>
</dd>
</li>
<dt><strong><a name="item_cond_broadcast">cond_broadcast VARIABLE</a></strong>
<dd>
<p>The <a href="#item_cond_broadcast"><code>cond_broadcast</code></a> function works similarly to <a href="#item_cond_signal"><code>cond_signal</code></a>.
<a href="#item_cond_broadcast"><code>cond_broadcast</code></a>, though, will unblock <strong>all</strong> the threads that are blocked in
a <a href="#item_cond_wait"><code>cond_wait</code></a> on the locked variable, rather than only one.</p>
</dd>
</li>
</dl>
<p>
</p>
<hr />
<h1><a name="objects">OBJECTS</a></h1>
<p><a href="../../lib/threads/shared.html">the threads::shared manpage</a> exports a version of <a href="../../lib/Pod/perlfunc.html#bless_ref">bless()</a> that
works on shared objects such that i<blessings> propagate across threads.</p>
<pre>
<span class="comment"># Create a shared 'foo' object</span>
<span class="keyword">my</span> <span class="variable">$foo</span><span class="operator">;</span>
<span class="variable">share</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">);</span>
<span class="variable">$foo</span> <span class="operator">=</span> <span class="operator">&</span><span class="variable">share</span><span class="operator">(</span><span class="operator">{}</span><span class="operator">);</span>
<span class="keyword">bless</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">,</span> <span class="string">'foo'</span><span class="operator">);</span>
</pre>
<pre>
<span class="comment"># Create a shared 'bar' object</span>
<span class="keyword">my</span> <span class="variable">$bar</span><span class="operator">;</span>
<span class="variable">share</span><span class="operator">(</span><span class="variable">$bar</span><span class="operator">);</span>
<span class="variable">$bar</span> <span class="operator">=</span> <span class="operator">&</span><span class="variable">share</span><span class="operator">(</span><span class="operator">{}</span><span class="operator">);</span>
<span class="keyword">bless</span><span class="operator">(</span><span class="variable">$bar</span><span class="operator">,</span> <span class="string">'bar'</span><span class="operator">);</span>
</pre>
<pre>
<span class="comment"># Put 'bar' inside 'foo'</span>
<span class="variable">$foo</span><span class="operator">-></span><span class="operator">{</span><span class="string">'bar'</span><span class="operator">}</span> <span class="operator">=</span> <span class="variable">$bar</span><span class="operator">;</span>
</pre>
<pre>
<span class="comment"># Rebless the objects via a thread</span>
<span class="variable">threads</span><span class="operator">-></span><span class="variable">create</span><span class="operator">(</span><span class="keyword">sub</span><span class="variable"> </span><span class="operator">{</span>
<span class="comment"># Rebless the outer object</span>
<span class="keyword">bless</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">,</span> <span class="string">'yin'</span><span class="operator">);</span>
</pre>
<pre>
<span class="comment"># Cannot directly rebless the inner object</span>
<span class="comment">#bless($foo->{'bar'}, 'yang');</span>
</pre>
<pre>
<span class="comment"># Retrieve and rebless the inner object</span>
<span class="keyword">my</span> <span class="variable">$obj</span> <span class="operator">=</span> <span class="variable">$foo</span><span class="operator">-></span><span class="operator">{</span><span class="string">'bar'</span><span class="operator">}</span><span class="operator">;</span>
<span class="keyword">bless</span><span class="operator">(</span><span class="variable">$obj</span><span class="operator">,</span> <span class="string">'yang'</span><span class="operator">);</span>
<span class="variable">$foo</span><span class="operator">-></span><span class="operator">{</span><span class="string">'bar'</span><span class="operator">}</span> <span class="operator">=</span> <span class="variable">$obj</span><span class="operator">;</span>
</pre>
<pre>
<span class="operator">})-></span><span class="keyword">join</span><span class="operator">();</span>
</pre>
<pre>
<span class="keyword">print</span><span class="operator">(</span><span class="keyword">ref</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">),</span> <span class="string">"\n"</span><span class="operator">);</span> <span class="comment"># Prints 'yin'</span>
<span class="keyword">print</span><span class="operator">(</span><span class="keyword">ref</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">-></span><span class="operator">{</span><span class="string">'bar'</span><span class="operator">}</span><span class="operator">),</span> <span class="string">"\n"</span><span class="operator">);</span> <span class="comment"># Prints 'yang'</span>
<span class="keyword">print</span><span class="operator">(</span><span class="keyword">ref</span><span class="operator">(</span><span class="variable">$bar</span><span class="operator">),</span> <span class="string">"\n"</span><span class="operator">);</span> <span class="comment"># Also prints 'yang'</span>
</pre>
<p>
</p>
<hr />
<h1><a name="notes">NOTES</a></h1>
<p>threads::shared is designed to disable itself silently if threads are not
available. If you want access to threads, you must <code>use threads</code> before you
<code>use threads::shared</code>. <a href="../../lib/threads.html">the threads manpage</a> will emit a warning if you use it after
<a href="../../lib/threads/shared.html">the threads::shared manpage</a>.</p>
<p>
</p>
<hr />
<h1><a name="bugs_and_limitations">BUGS AND LIMITATIONS</a></h1>
<p>When <a href="#item_share"><code>share</code></a> is used on arrays, hashes, array refs or hash refs, any data
they contain will be lost.</p>
<pre>
<span class="keyword">my</span> <span class="variable">@arr</span> <span class="operator">=</span> <span class="string">qw(foo bar baz)</span><span class="operator">;</span>
<span class="variable">share</span><span class="operator">(</span><span class="variable">@arr</span><span class="operator">);</span>
<span class="comment"># @arr is now empty (i.e., == ());</span>
</pre>
<pre>
<span class="comment"># Create a 'foo' object</span>
<span class="keyword">my</span> <span class="variable">$foo</span> <span class="operator">=</span> <span class="operator">{</span> <span class="string">'data'</span> <span class="operator">=></span> <span class="number">99</span> <span class="operator">}</span><span class="operator">;</span>
<span class="keyword">bless</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">,</span> <span class="string">'foo'</span><span class="operator">);</span>
</pre>
<pre>
<span class="comment"># Share the object</span>
<span class="variable">share</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">);</span> <span class="comment"># Contents are now wiped out</span>
<span class="keyword">print</span><span class="operator">(</span><span class="string">"ERROR: \$foo is empty\n"</span><span class="operator">)</span>
<span class="keyword">if</span> <span class="operator">(!</span> <span class="keyword">exists</span><span class="operator">(</span><span class="variable">$foo</span><span class="operator">-></span><span class="operator">{</span><span class="string">'data'</span><span class="operator">}</span><span class="operator">));</span>
</pre>
<p>Therefore, populate such variables <strong>after</strong> declaring them as shared. (Scalar
and scalar refs are not affected by this problem.)</p>
<p>It is often not wise to share an object unless the class itself has been
written to support sharing. For example, an object's destructor may get called
multiple times, one for each thread's scope exit. Another example, is that
the contents of hash-based objects will be lost due to the above mentioned
limitation.</p>
<p>Does not support <a href="../../lib/Pod/perlfunc.html#item_splice"><code>splice</code></a> on arrays!</p>
<p>Taking references to the elements of shared arrays and hashes does not
autovivify the elements, and neither does slicing a shared array/hash over
non-existent indices/keys autovivify the elements.</p>
<p><a href="#item_share"><code>share()</code></a> allows you to <a href="#item_share"><code>share($hashref->{key})</code></a> without giving any
error message. But the <code>$hashref->{key}</code> is <strong>not</strong> shared, causing the
error "locking can only be used on shared values" to occur when you attempt to
<a href="#item_lock"><code>lock($hasref->{key})</code></a>.</p>
<p>View existing bug reports at, and submit any new bugs, problems, patches, etc.
to: <a href="http://rt.cpan.org/NoAuth/Bugs.html?Dist=threads-shared">http://rt.cpan.org/NoAuth/Bugs.html</a></p>
<p>
</p>
<hr />
<h1><a name="see_also">SEE ALSO</a></h1>
<p><a href="../../lib/threads/shared.html">the threads::shared manpage</a> Discussion Forum on CPAN:
<a href="http://www.cpanforum.com/dist/threads-shared">http://www.cpanforum.com/dist/threads-shared</a></p>
<p>Annotated POD for <a href="../../lib/threads/shared.html">the threads::shared manpage</a>:
<a href="http://annocpan.org/~JDHEDDEN/threads-shared-1.01/shared.pm">http://annocpan.org/~JDHEDDEN/threads-shared-1.01/shared.pm</a></p>
<p><a href="../../lib/threads.html">the threads manpage</a>, <a href="../../lib/Pod/perlthrtut.html">the perlthrtut manpage</a></p>
<p><a href="http://www.perl.com/pub/a/2002/06/11/threads.html">http://www.perl.com/pub/a/2002/06/11/threads.html</a> and
<a href="http://www.perl.com/pub/a/2002/09/04/threads.html">http://www.perl.com/pub/a/2002/09/04/threads.html</a></p>
<p>Perl threads mailing list:
<a href="http://lists.cpan.org/showlist.cgi?name=iThreads">http://lists.cpan.org/showlist.cgi</a></p>
<p>
</p>
<hr />
<h1><a name="author">AUTHOR</a></h1>
<p>Artur Bergman <sky AT crucially DOT net></p>
<p>threads::shared is released under the same license as Perl.</p>
<p>Documentation borrowed from the old Thread.pm.</p>
<p>CPAN version produced by Jerry D. Hedden <jdhedden AT cpan DOT org>.</p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -