C# 中多線程鎖的使用經(jīng)驗:全局鎖,實例鎖
全局鎖
????????private static object _exeLock = new object();
? ? ? ?static 靜態(tài)的是全應(yīng)用程序的資源。如果在一個類里定義了這樣一個鎖,你在調(diào)用使用這個類的時候,是NEW了一個對象,并把這個對象給了一個靜態(tài)全局變量中保存。這時這個鎖就是全局鎖了。
? ? ? ? 你在調(diào)用帶鎖的方法時會受到【全局鎖】的影響。
實例鎖
????????private object _exeLock = new object();
? ? ? ? 影響只在這個對象實例中。
示例
全局鎖代碼
類的代碼
/// <summary>
/// 雷賽板卡 AxisDMC3000
/// </summary>
public class DMC3000 : AxisModel
{
public DMC3000() { }
public DMC3000(string name) { }
/// <summary>
/// 全局鎖
/// </summary>
private static object _exeLockAll = new object();
/// <summary>
/// 對象鎖
/// </summary>
//private object _exeLock = new object();
/// <summary>
/// 移動到指定位置
/// </summary>
/// <param name="posname">位置名稱</param>
/// <returns></returns>
public override bool MoveAbs(string posname)
{
var isFinsh = false;
lock (_exeLockAll)
{
try
{
int dis = (int)(GetAxisPosList(posname) * Param.PulseRatio);
SetAxisParam();
//單軸運動函數(shù)
//Dist 目標(biāo)位置,單位:pulse,范圍:-134217728~+134217728
//posi_mode 運動模式,0:相對坐標(biāo)模式,1:絕對坐標(biāo)模式
isFinsh = LTDMC.dmc_pmove(CardNum, AxisNum, dis, 1) == 0;
}
catch (Exception ex)
{
isFinsh = false;
WorkFlow.ShowMsgError("MoveAbs(string posname) 異常:" + ex.Message,
"MoveAbs(string posname)");
}
}
return isFinsh;
}
}
上面的代碼中有一個【全局鎖】和一個用了【全局鎖】的方法
調(diào)用這個類時的代碼
創(chuàng)建兩個類對象
#region 軸
/// <summary>
/// (焊接)X軸 左右移動X軸
/// </summary>
private static DMC3000 _axis_CarryX;
/// <summary>
/// (焊接)Y軸 前后移動Y軸
/// </summary>
private static DMC3000 _axis_CarryY;//Axis_CarryY = 1,
/// <summary>
/// 送針X 左右移動
/// </summary>
private static DMC3000 _axis_SongzhengX;
#endregion
/// <summary>
/// 初始化 軸
/// </summary>
/// <returns></returns>
public static bool InitAxis()
{
var isFinish = false;
_axis_CarryX = new DMC3000(AxisType.Axis_CarryX.ToString());
_axis_CarryY = new DMC3000(AxisType.Axis_CarryY.ToString());
_axis_SongzhengX = new DMC3000(AxisType.Axis_SongzhengX.ToString());
return isFinish;
}
上面三個軸都是new的方式生成是三個獨立的對象。
但在用線程Task調(diào)用MoveAbs方法時你會發(fā)現(xiàn),三個軸的運動情況是一個一個的移動。而不是同時移動的
public static void Test()
{
Task.Factory.StartNew(() => {
_axis_CarryX.MoveAbs("ToPos");
});
Task.Factory.StartNew(() => {
_axis_CarryY.MoveAbs("ToPos");
});
Task.Factory.StartNew(() => {
_axis_SongzhengX.MoveAbs("ToPos");
});
}
原因就是對象里使用對【全局鎖】每個對象在調(diào)用MoveAbs方法時都會進(jìn)行排對,第一個線程用完后,第二個線程去用。以此類推。這像就相對于是單線程了,上面開了三個線程去執(zhí)行,完全沒有用和不用Task調(diào)用是一樣的。這樣的效果一定不是我們所希望的。那要怎么解決這個問題呢。
? ? ? ? 有人可能會說那就不用鎖了。這樣不是解決問題了嗎?這也是一種解決方法。但我在工作中。發(fā)現(xiàn)一個問題就是在不用鎖時發(fā)現(xiàn)有時軸無法走到指定的點位。在獲取軸當(dāng)前的坐標(biāo)時也不是我們指定的坐標(biāo)位。本文就是為解決這個時而出現(xiàn)的多線程問題而寫的總結(jié)。
? ? ? ? 為了達(dá)到同步效果又要解決一個軸在多個線程中有調(diào)用的情況時。我選擇了【對象鎖】解決問題?!緦ο箧i】從名稱中就可以知道,這鎖的范圍在對象中,不會影響到其他對象的的調(diào)用。這樣就可以解決問題。多線程中同時調(diào)用MoveAbs方法時進(jìn)行鎖排對,執(zhí)行和取讀當(dāng)前坐標(biāo)不會因為多線程為影響。文章來源:http://www.zghlxwxcb.cn/news/detail-839633.html
實例鎖代碼
/// <summary>
/// 雷賽板卡 AxisDMC3000
/// </summary>
public class DMC3000 : AxisModel
{
public DMC3000() { }
public DMC3000(string name) { }
/// <summary>
/// 對象鎖
/// </summary>
private object _exeLock = new object();
/// <summary>
/// 移動到指定位置
/// </summary>
/// <param name="posname">位置名稱</param>
/// <returns></returns>
public override bool MoveAbs(string posname)
{
var isFinsh = false;
lock (_exeLock)
{
try
{
int dis = (int)(GetAxisPosList(posname) * Param.PulseRatio);
SetAxisParam();
//單軸運動函數(shù)
//Dist 目標(biāo)位置,單位:pulse,范圍:-134217728~+134217728
//posi_mode 運動模式,0:相對坐標(biāo)模式,1:絕對坐標(biāo)模式
isFinsh = LTDMC.dmc_pmove(CardNum, AxisNum, dis, 1) == 0;
}
catch (Exception ex)
{
isFinsh = false;
WorkFlow.ShowMsgError("MoveAbs(string posname) 異常:" + ex.Message,
"MoveAbs(string posname)");
}
}
return isFinsh;
}
}
代碼差別不大就中對像鎖中沒有使用static關(guān)鍵字。文章來源地址http://www.zghlxwxcb.cn/news/detail-839633.html
到了這里,關(guān)于C# 中多線程鎖的使用經(jīng)驗的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!