PDA

View Full Version : Semaphore



mzjahromi
سه شنبه 10 آبان 1384, 12:50 عصر
من تو دلفی برای انجام یه سری کارای همروند(Concurrent) از سمافور استفاده کردم ولی مشکلی که دارم اینه که وقتی دو تا نسخه از برنامه با دوتا کاربر جداگانه اجرا میشه(Administratorو Guest) سمافور درست کار نمی کنه

seyedof
چهارشنبه 11 آبان 1384, 05:16 صبح
سلام
شاید اسمهاشون یکی است بخاطر این کار نمیکنه.
ممنون علی

mzjahromi
چهارشنبه 11 آبان 1384, 17:13 عصر
اسمش که یکیه ولی وقتی یکی ازش رد میشه بقه باید پشتش بمونن. ولی نمی مونن

mzjahromi
چهارشنبه 11 آبان 1384, 17:14 عصر
همینطور وقتی وجود داره نباید دوباره ایجاد بشه ولی میشه

mzjahromi
دوشنبه 19 دی 1384, 21:11 عصر
کسی تو این زمینه تجربه ای نداره؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟ ؟؟؟

Inprise
سه شنبه 20 دی 1384, 02:35 صبح
به نظرت با این سوال مبهم و کلی و بدون کوچکترین توضیحی در مورد منطق برنامه و دلیل استفاده از سمافور و ...چه تجربه ای ممکنه به دردت بخوره ؟ قدم اول در گرفتن یه جواب ، پرسیدن یه سوال خوبه .

mzjahromi
سه شنبه 20 دی 1384, 08:38 صبح
ببخشید چشم.
من یه برنامه با DCom نوشته ام و از نوع Multiple Instance
حالا هر کاربر که متصل میشه یه Instance از RemoteDataModule ایجاد میشه.
اگر کاربر از یه کامپیوتر دیگه متصل بشه(در حالت WorkGroup) ویندوز اون رو با Guest میشناسه
اگر در تنظیمات DcomCnfg نوع کاربر Intractive User نباشد برای کسانی که Local از این برنامه استفاده میکنند، یک نسخه از َApplication اجرا میشود و برای کسانی که از روی سایر کامپیوتر ها به برنامه متصل میشوند یک نسخه دیگر که اجرا کننده اولی Administrator یا کاربر فعال است و اجرا کننده دومی Guest است
اول اینکه دو برنامه اجرا میشود آیا تنها راه آن استفاده از Intractive User هست؟(اینو میشه اینجوری حل کرد)
دوم فرض کنیم یک سمافور داریم که میخواهیم کنترل کنیم که دو کاربر به صورت همزمان اطلاعات یک قسمت از بانک رو ویرایش نکنند. فرض کنیدافزایش موجودی یا امثال اون.و بخواهیم وقتی یکی داره افزایش میده اونیکی صبر کنه.
حالا سمافور این کار رو برای ما انجام میده.
ولی یه مشکل اینجاست اونم اینکه
دو تا برنامه اجرا شده از طرف Guest و Administrator تنها یک سمافور(با یک نام) باید بتوانند ایجاد کنند. ولی دوتا ایجاد میشه. و کارهای Guest و Administrator که همروند هستند serialize نمیشن. یا به عبارتی هیچ کدوم با اونیکی کار نداره و هر کدوم کار خودش رو می کنه.
اگر دو تا نسخه اجرا شده توسط یک UserName اجرا شوند مشکلی ندارد ولی نو این حالت مشکل به وجود میاد

Inprise
چهارشنبه 21 دی 1384, 15:22 عصر
طبیعی است که هر کدام کار خودشون رو بکنند چون کاربران مختلف روی ویندوز از Context های مختلف برای ذخیره Credential هائی مانند این استفاده میکنند .

mzjahromi
چهارشنبه 21 دی 1384, 16:33 عصر
طبیعی است که هر کدام کار خودشون رو بکنند چون کاربران مختلف روی ویندوز از Context های مختلف برای ذخیره Credential هائی مانند این استفاده میکنند .
خوب حالا تو این شرایط که مشکل همروندی وجود داره چاره چیه؟

Inprise
چهارشنبه 21 دی 1384, 17:21 عصر
اصولا" مسئلهء تو ربطی به همروندی نداره ؛ اگه قراره دو برنامه یا ماژول مختلف متعلق به کاربران مختلف بصورت همزمان به رکوردی از بانک دسترسی نداشته باشند ، میتونی از طریق مدیر بانک ، دسترسی همزمان رو لغو کنی ، در نتیحه کاربر دوم منتظر اتمام وظیفه کاربر اول میمونه ، یا از یک Memeory Mapped File برای ثبت آخرین وضعیت دسترسی به منبع مورد نظر استفاده میکنی ، و هر نسخه از برنامه یا ماژول باید قبل از دسترسی به اون منبع ، آخرین وضعیت دسترسی بهش رو از طریق اون فایل چک کنند ؛ مسائل مرتبط با همروندی زمانی مطرح هستند که تو در حال تعامل با Thread های مختلف یک Process هستی ؛ وقتی که تو نسخه های مختلفی از ماژولت رو در زمان اجرا میسازی ، مسائلی که برات پیش میاد هیچ ربطی به Threading و مفاهیم مربوط به اون ندارند .

mzjahromi
چهارشنبه 21 دی 1384, 17:31 عصر
می دونم مساله با همروندی فرق داره ولی آیا نمیشه به روش Critical section مشکل رو حل کرد؟ وقتی یکی درون ناحیه بحرانی قرار داره باید بقیه صبر کنند. این همون چیزی هست که بخاطرش بحث سمافور پیش میاد. درسته اون روشی که شما میگید درسته. ولی تو این حالت به نظر شما سمافور کارائی نداره؟ اگر دوتا کاربر بخوان یه ناحیه بحرانی داشته باشن نمی تونن از سمافور کمک بگیرن؟

Inprise
چهارشنبه 21 دی 1384, 19:25 عصر
نکتهء ساده ای که باید بهش توجه کنی اینه که وقتی ، در حال استفاده از برنامه های اجرائی مختلف هستی ( ماژولهای DCOM هم در عمل بصورت یک Application مجزا اجرا میشن - در حالتیکه گفتی ) اصولا" فضای آدرسی در دسترس پروسه ها از هم جداست و بصورت عادی ، یکی به دیگری دسترسی نداره . Critical Section ای که در فضای آدرسی یک ماژول تعریف میشه ، برای همون ماژول و Thread های همون ماژول معتبره ، و ماژول دیگه ( درست تره بگم Process دیگه ) اصولا" در حالات عادی توانائی دیدن فضای ادرسی حافظه در اختیار پروسه های دیگر رو نداره ؛ که یعنی هر چیزی ذیل عنوان کلی همروندی ، کمکی به تو در این حالت خاص نخواهد کرد ، و باید دنبال یه روش دیگه باشی .

mzjahromi
چهارشنبه 21 دی 1384, 19:28 عصر
ممنون از راهنمائی تون

MiRHaDi
پنج شنبه 22 دی 1384, 03:50 صبح
سلام
برای این کار به نظر من بهتره مثلا یک Table مجازی درست کنی و وقتی هر کدوم از کاربرا به EditableMode وارد شد در رکورد مربوط به فیلد مربوطه یک متغیر Boolean رو Set و بعد از Post یا Cancle اون رو پاک کنی و برای ورود هر کاربر این فیلد رو چک کنی ...
هر چیزی تو درسها خوندیم که حتما نباید تو هر پروژه ای کاربرد داشته باشه :) سیستم عامل که نمینویسیم :)
بای

mzjahromi
پنج شنبه 22 دی 1384, 09:58 صبح
سلام
برای این کار به نظر من بهتره مثلا یک Table مجازی درست کنی و وقتی هر کدوم از کاربرا به EditableMode وارد شد در رکورد مربوط به فیلد مربوطه یک متغیر Boolean رو Set و بعد از Post یا Cancle اون رو پاک کنی و برای ورود هر کاربر این فیلد رو چک کنی ...
هر چیزی تو درسها خوندیم که حتما نباید تو هر پروژه ای کاربرد داشته باشه :) سیستم عامل که نمینویسیم :)
بای
آخه اگه کاربر Terminate شد و دیگه نتونست فیلد رو True کنه چی؟
اگر اون مسائل همزمانی اینجا پیش اومد چی؟ یعنی یکی خوند. تا بخواد True رو False کنه یکی دیگه هم خوند و این کار رو کرد. به این ترتیب دو نفر همزمان وارد مد Edit میشن.
مگه فاصله Editmode من چقدره؟؟ شاید به میلی ثانیه هم نرسه. ولی تو همین شرایط تست کردم اگه دوتا کاربر همزمان کلید Enter رو برای ثبت اطلاعات فشار بدن. مشکل بوجود میاد. یعنی یکی مینویسه و دیگری fail میشه.
دوست عزیز اونائی که خوندیم تو همین جاهای حساس بدردمون می خوره.
من حتی اگه این مساله رو بی خیال بشم شاید 1 در 1000 مورد هم تلاقی نداشته باشم ولی ما به عنوان یک برنامه نویس وظیفه داریم تا اونجائی که امکان داره جلو اینا رو بگیریم

Inprise
پنج شنبه 22 دی 1384, 17:34 عصر
مسئله دستکاری همزمان بانک رو باید از طریق بانک حل کنی ؛ عموم موتورها این اجازه رو بهت میدن که امکان دسترسی همزمان رو قفل کنی ؛ برای برقراری هماهنگی بین پروسه های مختلف هم چند روش متداول وجود داره ، در کنار روشهای ابتکاری و شخصی . یک روش خوب استفاده از یک Memory mapped file است ، هر پروسه هنگام انجام عمل خاصی که هماهنگی برای آن مد نظر است ، قبل از فعل "0" و بعد از آن "1" رو در ستون وضعیت مختص به خودش در فایل ثبت میکنه ، و هر پروسه ، هر بار قبل از انجام فعل مذکور ، یکبار ستون وضعیت تمام پروسه ها در فایل مذکور رو بررسی میکنه ، اگر طبق منطق برنامه اجازهء شروع داشت ، "0" اش رو وارد میکنه ، کار رو شروع میکنه و پس از اتمام موفقیت آمیز "1" اش رو ثبت میکنه . قاعدتا" اگر پروسه ای به دلیلی معقول یا نا معقولی "0" داشت و "1" نداشت ، سایر پروسه ها امکان انجام فعل مذکور رو نخواهند داشت ، یا طبق منطق برنامه عمل خاصی رو انجام میدن ، که برای مواقع قطع شدن ناخواستهء یکی از پروسه ها ، میشه از یک تایم استمپ هم در کنار "0" و "1" استفاده کرد ، که اگر پروسه ای مایل بود وارد عمل بشه ، ولی پروسهء قبلی "0" داشت و "1" نداشت ، و تایم استمپش از مقدار خاصی بزرگتر بود ، یعنی یه اتفاق بد افتاده ، پس او حق داره که "1" اون پروسه رو وارد کنه ، و "0" خودش رو بعد از اون ، و روند ادامه پیدا کنه ؛ Memory Mapped بودن این فایل کمک میکنه تعامل با فایل سریعتر از تعامل با دیسک باشه ، و تاخیر چشمگیری بوجود نیاد ؛ ولی بهر تقدیر ، صورت مساله ات مربوط به کانکارنسی و پردازشهای موازی و غیره نیست ، چون در این حوزه ، ما همیشه داخل فضای یک برنامه خاص و مشخص کار میکنیم ، نه بین چند برنامه ؛ وقتی یک سیستم قراره به این شکل کار کنه ، در واقع یه سیستم توزیع شده است ، و سیستمهای توزیع شده معمولا" از Messaging برای برقراری ارتباط و هماهنگی استفاده میکنند ، لیکن چون صورت مساله تو خیلی ساده است ، لازم نیست درگیر استفاده از پیامها و صفها و غیره بشی و همین فایل ، همراه با یک طراحی منطقی خوب مشکل رو حل میکنه .

MiRHaDi
شنبه 24 دی 1384, 03:02 صبح
سلام
مثل همیشه جواب کامل و جامع !
سری که درد نمیکنه رو دستمال نمیبندند !
try except هم چیر خوبیه :)
بای

mzjahromi
شنبه 24 دی 1384, 08:16 صبح
ممنون از شما جناب Inprise

سلام
مثل همیشه جواب کامل و جامع !
سری که درد نمیکنه رو دستمال نمیبندند !
try except هم چیر خوبیه :)
بای
حتما نمیشه از Try Except استفاده کرد دیگه.
تو شرایطی که من دارم اگه از Try Except استفاده بشه یه سری از کارهائی که کاربر انجام داده از بین میره و ....