Жіп қауіпсіз және атомның айырмашылығы неде?


жауап 1:

Жіп қауіпсіз - бұл бірнеше ағындарға қол жеткізген кезде проблемалар туындамайды. Атом дегеніміз - бөлінбейтін, бұл тұрғыда үзіліссіз синоним дегенді білдіреді.

Құлыптарды іске асырудың екі әдісі бар:

  1. Атом операцияларын аппараттық қолдау - тұтасымен орындалатын арнайы құрама нұсқаулар, мысалы B. Test- and-set. Ақылды бол (және оның салдарларын ескер) - Петерсон алгоритмі.

Егжей-тегжейлі сіздің мысалыңызда екеуі де белгісіз. егер мен дұрыс түсінсем, сіз мынаны білдіресіз:

public class Unsure {жеке объект ulock = жаңа объект (); public int Unsafe1 {алу; реттеу; } = 0; жеке int _unsafe2 = 0; public int Unsafe2 {get {lock (ulock) {return _unsafe2; }} set {lock (ulock) {_unsafe2 = мән; }}}}

Тест коды:

var u = жаңа қауіпті (); Параллель.For (0, 10000000, _ => {u.Unsafe1 ++;}); Параллель.For (0, 10000000, _ => {u.Unsafe2 ++;}); Console.WriteLine (string.Format («{0} - {1}», u.Unsafe1, u.Unsafe2));

Нәтиже (мүмкін болатындардың бірі):

4648265 - 4149827

Екі жағдайда да жаңартулардың жартысынан көбі жоғалып кетті.

Мұның себебі ++ атомдық емес - үш бөлек операция бар:

  1. Мәнге 1 мәнін қосыңыз.

Біз мұны атомдық операциямен қамтамасыз ете аламыз. Мұны істеудің көптеген жолдары бар, бірақ мұнда екі:

жалпыға бірдей класс Қауіпсіз {жеке объект ұясы = жаңа объект (); public int Safe1 {алу; реттеу; } қоғамдық жарамсыз SafeIncrement1 () {lock (ulock) {this.Safe1 ++; }} жеке int _safe2 = 0; public int Safe2 {алу {қайтару _safe2; } set {_safe2 = мән; }} ашық жарамсыз SafeIncrement2 () {Interlocked.Increment (сілтеме _safe2); }}

Тест коды:

var s = жаңа қауіпсіз (); Parallel.For (0, 10000000, _ => {am SafeIncrement1 ();}); Parallel.For (0, 10000000, _ => {am SafeIncrement2 ();}); Console.WriteLine (string.Format («{0} - {1}», Safe1-де, Safe2-де));

Екі жағдайда да нәтижелер дұрыс. Біріншісі бүкіл құрама ++ әрекетін құлыптайды, екіншісі атомдық операцияларға аппараттық қолдауды қолданады.

Назар аударыңыз, Interlocked.Increment-тің жоғарыдағы екінші нұсқасы әлдеқайда жылдам, бірақ іс жүзінде төменгі деңгейге ие және тек шектеулі функцияны ұсынады. Алайда бұғатталған пакеттегі операцияларды келесі әрекеттерді орындау үшін пайдалануға болады:

  1. «Пессимистік параллелизм» деп аталатын әйгілі құлыптар, олар процесс үзіледі деп есептегендіктен, олар ортақ ресурс алғанға дейін басталмайды. Салыстыру және ауыстыру кезінде сіз арнайы жазған «Канар» мәнін қолданыңыз, содан кейін соңында ештеңе өзгермегеніне көз жеткізіңіз. Идея: тағы бір жіп канарды өлтіреді, сондықтан сіз транзакцияны басынан бастап қайталау керек екенін білесіз. Бұл сіздің жеке кодыңыз атомдық болып табылады. Ортақ күйге аралық нәтижелерді жаза алмайсыз. Сіз толығымен сәтті болуыңыз керек немесе толықтай сәтсіздікке ұшырауыңыз керек (сіз ешқандай операция жасамаған сияқты).

жауап 2:

Екі мүлдем басқа нәрсе. Жіп қауіпсіз - бұл әр түрлі жіптермен бірнеше рет қайталануы мүмкін, әр жіп басқа жіптің функциясына кедергі келтірместен жазылатын функция (мысалы, егер бір айнымалысын басқасы өзгертсе, оның мәнін өзгерту арқылы). Жіп қолданылады).

Атом дегеніміз (егер сіз қайда бара жатқаныңызды білсем), объектінің данасы құрылатындығын білдіреді. Қанша сілтеме жасалса да, бұл бір данасы (кез-келген жіптен) әрқашан көрсетіледі.


жауап 3:

Атомдық операциялар - бұл ішкі операцияларды қолданатын мексекс немесе семафор сияқты құлыптау түрін қолдану арқылы немесе атомдық және сақтау қоршауларын қолдана отырып, құлыпсыз синхрондауды қолдану арқылы жіп қауіпсіздігіне қол жеткізудің тәсілі.

Қарапайым мәліметтер типіндегі атомдық операциялар, сондықтан ағындардың қауіпсіздігіне қол жеткізу құралы болып табылады, бірақ автоматты түрде жіп қауіпсіздігіне кепілдік бермейді, өйткені сіз әдетте бір-біріңізге сүйенетін бірнеше операцияларды орындайсыз. Сіз бұл әрекеттердің үздіксіз орындалуын қамтамасыз етуіңіз керек, мысалы, B. муексексімен.

Ия, осы атомдық мәліметтердің біреуін C # түрінде жазу жіппен қауіпсіз, бірақ бұл сіз қолданған функцияны қауіпсіз ете алмайды. Бұл тек бір жазудың дұрыс орындалуын қамтамасыз етеді, тіпті егер екінші жіп оған «бір уақытта» кірсе. Қалай болғанда да, сіз келесі жолдан оқыған кезде, ол бұрын жазылған мәннің сақталатындығына кепілдік бермейді, өйткені оған басқа ағын жазылған болуы мүмкін, бірақ тек оқу мәні жарамды.