نمایش نتایج 1 تا 7 از 7

نام تاپیک: استفاده از کلاس Monitor در کنترل Thread

  1. #1
    کاربر دائمی
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    ????? - ??????
    پست
    424

    استفاده از کلاس Monitor در کنترل Thread

    سلام.

    من یه برنامه تحت شبکه ساخته ام که روال کلیش به صورت زیره:

    کاربران وقتی به سرور متصل میشوند و کانکت میشوند برایشان یک Thread ساخته می شود یهنی به ازای هر کاربر یه Thread ساخته میشه که در این Thread حلقه دریافت اطلاعات از کاربر قرار داره.

    یه کلاس دیگه دارم که یه صفه (Queue) ودر این صف اطلاعات از Thread ها به داخل این صف وارد می شوند و مورد پردازش قرار گرفته و جواب به کاربر ارسال می گردد.

    حالا من برای مدیریت این Thread ها می خوام از کلاس Monitor استفاده کنم. ولی نمیدونم چه طوری باید استفاده و کنم و کجا ازش استفاده بشه!!

    لطفا کمکم کنید.

    -------------------------------------------------------------------------------------------------------------------------------------------------------
    وب

  2. #2

    نقل قول: استفاده از کلاس Monitor در کنترل Thread

    Thread های شما Producer و Thread ای که از صف نتایج رو بر میگردونه Consumer هست. شما سناریوی Producer/Consumer رو در برنامتون دارید.
    How to: Implement a Producer-Consumer Dataflow Pattern

  3. #3
    کاربر دائمی
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    ????? - ??????
    پست
    424

    نقل قول: استفاده از کلاس Monitor در کنترل Thread

    نقل قول نوشته شده توسط tooraj_azizi_1035 مشاهده تاپیک
    Thread های شما Producer و Thread ای که از صف نتایج رو بر میگردونه Consumer هست. شما سناریوی Producer/Consumer رو در برنامتون دارید.
    How to: Implement a Producer-Consumer Dataflow Pattern
    میشه بیشتر توضیح بدین من از این صفحه چیزی نفهمیدم!!

  4. #4
    کاربر دائمی
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    ????? - ??????
    پست
    424

    نقل قول: استفاده از کلاس Monitor در کنترل Thread

    کسی نیست به من کمک کنه؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟

  5. #5

    نقل قول: استفاده از کلاس Monitor در کنترل Thread

    ساختمان داده ConcurrentQueue رو پیشنهاد می کنم. یک صف هست که چندین ترد می تونن همزمان به اون آیتم اضافه می کنن.
    اضافه کردن با متد Enqueue هست و برداشتن از صف با متد TryDequeue.
    تمام هماهنگی ها به طور داخلی در طراحی این کلاس در نظر گرفته شده و شما مسئول Sync ترد ها نیستید و استفاده از Monitor منتفی هست.

    البته اگر اصرار بر FIFO بودن دارید باید از صف استفاده کنید چون آیتمی که آخر وارد می شود حتماً اول برداشته می شود.


    ConcurrentQueue<T> handles all synchronization internally. If two threads call TryDequeue at precisely the same moment, neither operation is blocked. When a conflict is detected between two threads, one thread has to try again to retrieve the next element, and the synchronization is handled internally.
    TryDequeue tries to remove an element from the queue. If the method is successful, the item is removed and the method returns true; otherwise, it returns false. That happens atomically with respect to other operations on the queue. If the queue was populated with code such as q.Enqueue("a"); q.Enqueue("b"); q.Enqueue("c"); and two threads concurrently try to dequeue an element, one thread will dequeue a and the other thread will dequeue b. Both calls to TryDequeue will return true, because they were both able to dequeue an element. If each thread goes back to dequeue an additional element, one of the threads will dequeue c and return true, whereas the other thread will find the queue empty and will return false.


  6. #6
    کاربر دائمی
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    ????? - ??????
    پست
    424

    نقل قول: استفاده از کلاس Monitor در کنترل Thread

    نقل قول نوشته شده توسط tooraj_azizi_1035 مشاهده تاپیک
    ساختمان داده ConcurrentQueue رو پیشنهاد می کنم. یک صف هست که چندین ترد می تونن همزمان به اون آیتم اضافه می کنن.
    اضافه کردن با متد Enqueue هست و برداشتن از صف با متد TryDequeue.
    تمام هماهنگی ها به طور داخلی در طراحی این کلاس در نظر گرفته شده و شما مسئول Sync ترد ها نیستید و استفاده از Monitor منتفی هست.

    البته اگر اصرار بر FIFO بودن دارید باید از صف استفاده کنید چون آیتمی که آخر وارد می شود حتماً اول برداشته می شود.


    ConcurrentQueue<T> handles all synchronization internally. If two threads call TryDequeue at precisely the same moment, neither operation is blocked. When a conflict is detected between two threads, one thread has to try again to retrieve the next element, and the synchronization is handled internally.
    TryDequeue tries to remove an element from the queue. If the method is successful, the item is removed and the method returns true; otherwise, it returns false. That happens atomically with respect to other operations on the queue. If the queue was populated with code such as q.Enqueue("a"); q.Enqueue("b"); q.Enqueue("c"); and two threads concurrently try to dequeue an element, one thread will dequeue a and the other thread will dequeue b. Both calls to TryDequeue will return true, because they were both able to dequeue an element. If each thread goes back to dequeue an additional element, one of the threads will dequeue c and return true, whereas the other thread will find the queue empty and will return false.

    از این اینکه این ساختمان را به من معرفی کردید سپاسگذارم ولی اگه میشه طرز استفاده از کلاس monitor را هم برایم بگید

  7. #7

    نقل قول: استفاده از کلاس Monitor در کنترل Thread

    کلاس Monitor دارای متدی به نام Enter هست که ورود به ناحیه بحرانی رو اعلام می کنه و متد Exit خروج رو اعلام میکنه.
    همون صف با هماهنگی Monitor:
    http://msdn.microsoft.com/en-us/library/de0542zz.aspx


    using System;
    using System.Threading;
    using System.Collections.Generic;
    using System.Text;

    class SafeQueue<T>
    {
    // A queue that is protected by Monitor.
    private Queue<T> m_inputQueue = new Queue<T>();

    // Lock the queue and add an element.
    public void Enqueue(T qValue)
    {
    // Request the lock, and block until it is obtained.
    Monitor.Enter(m_inputQueue);
    try
    {
    // When the lock is obtained, add an element.
    m_inputQueue.Enqueue(qValue);
    }
    finally
    {
    // Ensure that the lock is released.
    Monitor.Exit(m_inputQueue);
    }
    }

    // Try to add an element to the queue: Add the element to the queue
    // only if the lock is immediately available.
    public bool TryEnqueue(T qValue)
    {
    // Request the lock.
    if (Monitor.TryEnter(m_inputQueue))
    {
    try
    {
    m_inputQueue.Enqueue(qValue);
    }
    finally
    {
    // Ensure that the lock is released.
    Monitor.Exit(m_inputQueue);
    }
    return true;
    }
    else
    {
    return false;
    }
    }

    // Try to add an element to the queue: Add the element to the queue
    // only if the lock becomes available during the specified time
    // interval.
    public bool TryEnqueue(T qValue, int waitTime)
    {
    // Request the lock.
    if (Monitor.TryEnter(m_inputQueue, waitTime))
    {
    try
    {
    m_inputQueue.Enqueue(qValue);
    }
    finally
    {
    // Ensure that the lock is released.
    Monitor.Exit(m_inputQueue);
    }
    return true;
    }
    else
    {
    return false;
    }
    }

    // Lock the queue and dequeue an element.
    public T Dequeue()
    {
    T retval;

    // Request the lock, and block until it is obtained.
    Monitor.Enter(m_inputQueue);
    try
    {
    // When the lock is obtained, dequeue an element.
    retval = m_inputQueue.Dequeue();
    }
    finally
    {
    // Ensure that the lock is released.
    Monitor.Exit(m_inputQueue);
    }

    return retval;
    }

    // Delete all elements that equal the given object.
    public int Remove(T qValue)
    {
    int removedCt = 0;

    // Wait until the lock is available and lock the queue.
    Monitor.Enter(m_inputQueue);
    try
    {
    int counter = m_inputQueue.Count;
    while (counter > 0)
    // Check each element.
    {
    T elem = m_inputQueue.Dequeue();
    if (!elem.Equals(qValue))
    {
    m_inputQueue.Enqueue(elem);
    }
    else
    {
    // Keep a count of items removed.
    removedCt += 1;
    }
    counter = counter - 1;
    }
    }
    finally
    {
    // Ensure that the lock is released.
    Monitor.Exit(m_inputQueue);
    }

    return removedCt;
    }

    // Print all queue elements.
    public string PrintAllElements()
    {
    StringBuilder output = new StringBuilder();

    // Lock the queue.
    Monitor.Enter(m_inputQueue);
    try
    {
    foreach( T elem in m_inputQueue )
    {
    // Print the next element.
    output.AppendLine(elem.ToString());
    }
    }
    finally
    {
    // Ensure that the lock is released.
    Monitor.Exit(m_inputQueue);
    }

    return output.ToString();
    }
    }

    public class Example
    {
    private static SafeQueue<int> q = new SafeQueue<int>();
    private static int threadsRunning = 0;
    private static int[][] results = new int[3][];

    static void Main()
    {
    Console.WriteLine("Working...");

    for(int i = 0; i < 3; i++)
    {
    Thread t = new Thread(ThreadProc);
    t.Start(i);
    Interlocked.Increment(ref threadsRunning);
    }
    }

    private static void ThreadProc(object state)
    {
    DateTime finish = DateTime.Now.AddSeconds(10);
    Random rand = new Random();
    int[] result = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    int threadNum = (int) state;

    while (DateTime.Now < finish)

    {
    int what = rand.Next(250);
    int how = rand.Next(100);

    if (how < 16)
    {
    q.Enqueue(what);
    result[(int)ThreadResultIndex.EnqueueCt] += 1;
    }
    else if (how < 32)
    {
    if (q.TryEnqueue(what))
    {
    result[(int)ThreadResultIndex.TryEnqueueSucceedCt] += 1;
    }
    else
    {
    result[(int)ThreadResultIndex.TryEnqueueFailCt] += 1;
    }
    }
    else if (how < 48)
    {
    // Even a very small wait significantly increases the success
    // rate of the conditional enqueue operation.
    if (q.TryEnqueue(what, 10))
    {
    result[(int)ThreadResultIndex.TryEnqueueWaitSucceedCt] += 1;
    }
    else
    {
    result[(int)ThreadResultIndex.TryEnqueueWaitFailCt] += 1;
    }
    }
    else if (how < 96)
    {
    result[(int)ThreadResultIndex.DequeueCt] += 1;
    try
    {
    q.Dequeue();
    }
    catch
    {
    result[(int)ThreadResultIndex.DequeueExCt] += 1;
    }
    }
    else
    {
    result[(int)ThreadResultIndex.RemoveCt] += 1;
    result[(int)ThreadResultIndex.RemovedCt] += q.Remove(what);
    }
    }

    results[threadNum] = result;

    if (0 == Interlocked.Decrement(ref threadsRunning))
    {
    StringBuilder sb = new StringBuilder(
    " Thread 1 Thread 2 Thread 3 Total\n");

    for(int row = 0; row < 9; row++)
    {
    int total = 0;
    sb.Append(titles[row]);

    for(int col = 0; col < 3; col++)
    {
    sb.Append(String.Format("{0,9}", results[col][row]));
    total += results[col][row];
    }

    sb.AppendLine(String.Format("{0,9}", total));
    }

    Console.WriteLine(sb.ToString());
    }
    }

    private static string[] titles = {
    "Enqueue ",
    "TryEnqueue succeeded ",
    "TryEnqueue failed ",
    "TryEnqueue(T, wait) succeeded ",
    "TryEnqueue(T, wait) failed ",
    "Dequeue attempts ",
    "Dequeue exceptions ",
    "Remove operations ",
    "Queue elements removed "};

    private enum ThreadResultIndex
    {
    EnqueueCt,
    TryEnqueueSucceedCt,
    TryEnqueueFailCt,
    TryEnqueueWaitSucceedCt,
    TryEnqueueWaitFailCt,
    DequeueCt,
    DequeueExCt,
    RemoveCt,
    RemovedCt
    };
    }

    /* This example produces output similar to the following:

    Working...
    Thread 1 Thread 2 Thread 3 Total
    Enqueue 277382 515209 308464 1101055
    TryEnqueue succeeded 276873 514621 308099 1099593
    TryEnqueue failed 109 181 134 424
    TryEnqueue(T, wait) succeeded 276913 514434 307607 1098954
    TryEnqueue(T, wait) failed 2 0 0 2
    Dequeue attempts 830980 1544081 924164 3299225
    Dequeue exceptions 12102 21589 13539 47230
    Remove operations 69550 129479 77351 276380
    Queue elements removed 11957 22572 13043 47572
    */

تاپیک های مشابه

  1. استفاده از موبایل به جای کنترل تلویزیون
    نوشته شده توسط sharareh در بخش برنامه نویسی موبایل
    پاسخ: 11
    آخرین پست: شنبه 26 خرداد 1386, 18:28 عصر
  2. تولید قفل نرم افزاری با استفاده از کلاس های Security
    نوشته شده توسط Amir Taghavi در بخش VB.NET
    پاسخ: 3
    آخرین پست: چهارشنبه 12 بهمن 1384, 22:59 عصر
  3. استفاده از کلاس های ATL در برنامه های MFC
    نوشته شده توسط taze kar در بخش برنامه نویسی با زبان C و ++C
    پاسخ: 5
    آخرین پست: چهارشنبه 18 آبان 1384, 12:20 عصر
  4. مشکل در استفاده از کلاس pen
    نوشته شده توسط MF در بخش C#‎‎
    پاسخ: 1
    آخرین پست: سه شنبه 28 تیر 1384, 10:25 صبح
  5. استفاده از متود Finalize و کنترل Garbage Collector
    نوشته شده توسط marandi در بخش VB.NET
    پاسخ: 0
    آخرین پست: یک شنبه 14 دی 1382, 03:00 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •