日期:2014-05-18 浏览次数:20857 次
int g_x = 0; void ThreadFunc1() { g_x++; } void ThreadFunc2() { g_x++; }
------解决方案--------------------
我来给个清楚的解释吧 。。。
理论上是这样的:
当线程A与线程B并发执行“tally += 1;”时,这个期间就会发生资源(tally值)的同步问题,具体步骤如下所述:
1. A读取tally值
2. A对tally 进行 +1 操作
3. 线程发生切换
4. B读取tally值
5. B对tally 进行 +1 操作
6. B(往寄存器)写回tally 的新值
7. 线程发生切换
8. A(...)写回tally 的新值
-----------------不知道大家看明白没有,但是以上只是情况之一,还有更混乱的情况大家可以举一反三。
然而实际上的情况是:
目前PC上(包括很多的嵌入式机器)的数学运算(尤其是这样的加法运算)的速率很快的,LZ的题目的正确答案在目前的PC上肯定是100的,因为线程A与线程B均可被完全执行。
后话:
其实关于线程资源的互斥问题,并不可以完全的按照教科书式的进行盲目的lock操作,有很多需要大家仔细琢磨体会的小技术,小细节,这样才能达到安全与效率都完美的境界。
------解决方案--------------------
我的实验:
为了保证问题好复现,循环累加5000次,两个线程的循环将累加操作10000次。
测试一:按照问题测试,最后结果不一定是两个循环的累加和)。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click( object sender,EventArgs e)
{
value = 0;
textBox1.Text = value.ToString();
Thread th1 = new Thread(func);
Thread th2 = new Thread(func);
th1.Start();
th2.Start();
}
//Mutex mvalue = new Mutex();
int value = 0;
void func()
{ int i = 0;
for (i = 0; i < 5000; i++)
{
//mvalue.WaitOne();
value++;
//mvalue.ReleaseMutex();
// 显示刷新
setText();
// 给刷新留出时间
Thread .Sleep(1);
}
}
delegate void setTextCallBack();
void setText()
{
if (textBox1.InvokeRequired)