⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subject_65178.htm

📁 vc
💻 HTM
字号:
<p>
序号:65178 发表者:badboy 发表日期:2003-12-16 09:47:21
<br>主题:临界区自己可以实现多线程同步吗?
<br>内容:我觉得临界区最多只能保护一下全局变量而已。光靠临界区自己的,有同步控制线程的能力吗?<BR>&nbsp;&nbsp;下面我帖了一个程序的源代码!
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:badboy 回复日期:2003-12-16 12:11:35
<br>内容:不好意思!上面的源代码有点问题!&nbsp;&nbsp;重新帖!
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:BigJames 回复日期:2003-12-16 12:59:20
<br>内容:可以的。有什么问题吗?
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:微笑的撒旦 回复日期:2003-12-17 17:18:28
<br>内容:你说的没错,临界区只提供互斥访问。线程同步,不同的需求需要使用不同的技术,比如信号量,内核对象什么的。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:badboy 回复日期:2003-12-21 18:36:14
<br>内容:师傅,您也来了!这个帖子一直不敢回!我想自己能解决的就自己解决,怕耽误您宝贵的时间。第一楼的那个程序我基本快搞定了!不过,还是有点小问题,这个问题,不太重要,您有时间就看看!我有的时候太钻牛角尖。<BR>&nbsp;&nbsp;我原来的问题问得有点不对头,临界区本来就可以实现多个线程的同步,只是不采用一些非常代码是不能控制各个线程特定顺序。我原来以为临界区只能保护一下全局变量而已。不能依靠临界区来实现类似于<BR> thread1-&gt;thread2-&gt;thread1-&gt;thread2……这种特定顺序的线程同步。经过几天的研究,发现可以。不过,又有了新问题!<BR>我给您举个例子!&nbsp;&nbsp;下面这个程序竟然只用了sleep()函数就可以控制两个线程出现特定的同步顺序<BR>thread1-&gt;thread2-&gt;thread1-&gt;thread2……&nbsp;&nbsp;<BR>&nbsp;&nbsp; 而实际上,我是准备用一些特定代码实现两个线程同步的。见最下面的程序!<BR>#include &#34;iostream.h&#34;<BR>#include &lt;stdio.h&gt;<BR>#include &#34;process.h&#34;<BR>#include &#34;windows.h&#34;<BR>#include &lt;conio.h&gt;<BR>int _k;&nbsp;&nbsp; <BR>CRITICAL_SECTION&nbsp;&nbsp;_cs; <BR>int e=0; <BR>void thread1(void*) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;for(;!e;)&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnterCriticalSection(&amp;_cs);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++_k; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;_k&lt;&lt;&#34;&nbsp;&nbsp;&#34;&lt;&lt;&#34;this num&nbsp;&nbsp;is produecd by thread1&#34;&lt;&lt;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;Sleep(0);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;//让前面的这个函数工作一下,保证让你吓一跳!<BR>//我还没有采取任何同步的措施,这个程序就已经开始出现了<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//thread1-&gt;thread2-&gt;thread1-&gt;thread2……&nbsp;&nbsp;这个特定的线程同步顺序?是怎么出现的?<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//这个Sleep(0)函数到底搞了什么小动作?<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(&amp;_cs);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;_endthread();<BR>}<BR><BR>void thread2(void*) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;for(;!e;) <BR>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnterCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++_k; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(1000);&nbsp;&nbsp;&nbsp;&nbsp;//这里的时间可以随便改,甚至可以为0 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;_k&lt;&lt;&#34;&nbsp;&nbsp;&nbsp;&nbsp;&#34;&lt;&lt;&#34;this num is produced by thread2&#34;&lt;&lt;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;_endthread();<BR>}<BR><BR>int main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;InitializeCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;_beginthread(thread1,1024,NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;_beginthread(thread2,1024,NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;e=getch();&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;DeleteCriticalSection(&amp;_cs);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return 0;<BR>}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;_endthread();<BR>}<BR><BR>int main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;InitializeCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;_beginthread(thread1,1024,NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;_beginthread(thread2,1024,NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;e=getch();&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;DeleteCriticalSection(&amp;_cs);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return 0;<BR>}<BR>/*<BR>下面的这个程序才用了一些特定代码可以实现两个线程thread1-&gt;thread2-&gt;thread1-&gt;thread2……特定同步顺序。您一分析,就能确定下面这个程序肯定能实现两个线程的精确的交替执行,可上面那个程序凭什么呀? */<BR>#include &#34;iostream.h&#34;<BR>#include &lt;stdio.h&gt;<BR>#include &#34;process.h&#34;<BR>#include &#34;windows.h&#34;<BR>#include &lt;conio.h&gt;<BR>int _k; <BR>CRITICAL_SECTION&nbsp;&nbsp;_cs; <BR>int e=0; <BR>void thread1(void*)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;for(;!e;)&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(;;)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnterCriticalSection(&amp;_cs);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(_k%2==0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++_k;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(&amp;_cs);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;_k&lt;&lt;&#34;&nbsp;&nbsp;&#34;&lt;&lt;&#34;this num&nbsp;&nbsp;is produecd by thread1&#34;&lt;&lt;endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;_endthread(); <BR>}<BR><BR>void thread2(void*)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;for(;!e;)&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(;;)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnterCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(_k%2 != 0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++_k;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;_k&lt;&lt;&#34;&nbsp;&nbsp;&nbsp;&nbsp;&#34;&lt;&lt;&#34;this num is produced by thread2&#34;&lt;&lt;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp; _endthread(); <BR>}<BR><BR>int main()<BR>{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;InitializeCriticalSection(&amp;_cs);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _beginthread(thread1,1024,NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;_beginthread(thread2,1024,NULL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;e=getch();&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;DeleteCriticalSection(&amp;_cs); <BR>&nbsp;&nbsp;&nbsp;&nbsp;return 0;<BR>}<BR><BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:BigJames 回复日期:2003-12-21 21:11:51
<br>内容:下面是你的第一个例子,里面不是有EnterCriticalSection(&amp;_cs)和LeaveCriticalSection(&amp;_cs);了吗?和第二个一样呀!只不过第二个例子线程调度的机制略有不同而已。<BR><BR>void thread1(void*) <BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;for(;!e;)&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnterCriticalSection(&amp;_cs);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++_k; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;_k&lt;&lt;&#34;&nbsp;&nbsp;&#34;&lt;&lt;&#34;this num&nbsp;&nbsp;is produecd by thread1&#34;&lt;&lt;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;Sleep(0);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;//让前面的这个函数工作一下,保证让你吓一跳!<BR>//我还没有采取任何同步的措施,这个程序就已经开始出现了<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//thread1-&gt;thread2-&gt;thread1-&gt;thread2……&nbsp;&nbsp;这个特定的线程同步顺序?是怎么出现的?<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//这个Sleep(0)函数到底搞了什么小动作?<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LeaveCriticalSection(&amp;_cs);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;_endthread();<BR>}
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:BigJames 回复日期:2003-12-21 21:14:48
<br>内容:sleep(0)的作用仅仅是通知系统本thread放弃当前的执行机会,只有这样,thread2才会有机会获得运行的机会。<BR>sleep不是用来同步的。<BR><BR>关于sleep(0)可以看一下msdn,里面有讲的。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
<font color=red>答案被接受</font><br>回复者:微笑的撒旦 回复日期:2003-12-23 10:08:06
<br>内容:你的第一个例子并不能实现“线程的交替执行”!<BR>临界区的意思是:当线程进入临界区之后,在它退出临界区之前其他线程不能访问次临界区中的资源。<BR>在这里,thread1进入了_cs临界区之后,thread2就无法再访问变量_k。因为thread1中的Sleep()函数被commentd掉了,所以会比thread2执行更多次,最后的输出应该是很多条thread1后跟一条thread2。<BR><BR>第二个例子,其实也不能说是“线程的交替执行”,它只是控制了线程对变量的交替访问,但这也算是线程同步的意义。<BR>thread1输出偶数变量,如果_k不是偶数,则使用循环来等待(其实也是一种监听);thread2也一样。当thread1进入临界区后,thread2肯定也在监听,只等thread1退出临界区,thread2就可以进入_cs执行。而当thread1执行完之后,它会首先进入临界区,但是因为_k为奇数而无法执行++_k,所以最后由thread2执行此奇数的++。<BR>你可以把两个thread中的if(_k%2==0)行注释掉,会看到连续的几条thread1后出现连续的thread2,而具体的执行结果与系统有关。<BR><BR>线程同步是一个比较大的话题,为了实现它你可能需要写很多附加的代码,虽然有很多方法,但最后的效果才是最重要的。如果能解决问题,那种方法就是很好的。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -