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

نام تاپیک: مشکل ارسال Reference اشیاء بین دو thread

  1. #1
    کاربر دائمی آواتار m2011kh
    تاریخ عضویت
    فروردین 1390
    محل زندگی
    (Zweifall (Nordrhein-Westfalen
    پست
    646

    Question مشکل ارسال Reference اشیاء بین دو thread

    سلام و خسته نباشید خدمت دوستان عزیز.


    سوال بنده از این قرار هست. در حالت عادی میشه به عنوان پارامتر یک یا آرایه ای از رفرنس های اشیاء رو از شیئی به شیئ دیگر فرستاد. حالا مسئله اینجاست:

    تا اونجایی که بنده متوجه شدم ارجاع رفرنسی از شیئی بین دو کلاس به عنوان پارامتری از یک تابع در حالتی که بین دو نخ مختلف باشند ممکن نیست. الان سوال بنده اینه که وقتی که چند نخ داریم، این ارجاع رفرنس ها بین توابع و کلاس هارو در کل چطور باید کنترل و مدیریت کرد؟

    دوستان اگه مقاله ای یا پاسخی در این مورد دارید، ممنون میشم که پست کنید.

    موفق و سربلند باشید.


  2. #2

    نقل قول: مشکل ارسال Reference اشیاء بین دو thread

    نقل قول نوشته شده توسط m2011kh مشاهده تاپیک
    سلام و خسته نباشد.
    شرمنده كه اسپم ميدم ولي واقعا يعني كسي جوابي براي اين سوال نداشت؟
    امیدوارم به دردت بخوره.


    typedef struct
    {
    double *a;
    double *b;
    double sum;
    int veclen;
    } DOTDATA;

    /* Define globally accessible variables and a mutex */

    #define NUMTHRDS 4
    #define VECLEN 100

    DOTDATA dotstr; //GLOBAL DATA which is going to be accessed by different threads

    pthread_t callThd[NUMTHRDS];
    pthread_mutex_t mutexsum;

    void *dotprod(void *arg)
    {

    /* Define and use local variables for convenience */

    int i, start, end, len ;
    long offset;
    double mysum, *x, *y;
    offset = (long)arg;

    len = dotstr.veclen;
    start = offset*len;
    end = start + len;
    x = dotstr.a;
    y = dotstr.b;

    /*
    Perform the dot product and assign result
    to the appropriate variable in the structure.
    */

    mysum = 0;
    for (i=start; i<end ; i++)
    {
    mysum += (x[i] * y[i]);
    }

    /*
    Lock a mutex prior to updating the value in the shared
    structure, and unlock it upon updating.
    */
    pthread_mutex_lock (&mutexsum);
    dotstr.sum += mysum;
    pthread_mutex_unlock (&mutexsum);

    pthread_exit((void*) 0);
    }

    int main (int argc, char *argv[])
    {
    long i;
    double *a, *b;
    void *status;

    /* Assign storage and initialize values */
    a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
    b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));

    for (i=0; i<VECLEN*NUMTHRDS; i++)
    {
    a[i]=1.0;
    b[i]=a[i];
    }

    dotstr.veclen = VECLEN;
    dotstr.a = a;
    dotstr.b = b;
    dotstr.sum=0;

    pthread_mutex_init(&mutexsum, NULL);

    for(i=0; i<NUMTHRDS; i++)
    {
    /*
    Each thread works on a different set of data.
    The offset is specified by 'i'. The size of
    the data for each thread is indicated by VECLEN.
    */
    pthread_create(&callThd[i], NULL, dotprod, (void *)i);
    }

    /* Wait on the other threads */
    for(i=0; i<NUMTHRDS; i++)
    {
    pthread_join(callThd[i], &status);
    }

    printf ("Sum = %f \n", dotstr.sum);
    free (a);
    free (b);
    pthread_mutex_destroy(&mutexsum);
    pthread_exit(NULL);//No need of pthread_join() if pthread_exit() used.
    }







    class Program
    {
    static void Main()
    {
    Thread FirstThread = new Thread(new ThreadStart(Fun1));
    Thread SecondThread = new Thread(new ThreadStart(Fun2));
    FirstThread.Start();
    SecondThread.Start();


    }
    public static void Fun1()
    {
    for (int i = 1; i <= 1000; i++)
    {
    Console.WriteLine("Fun1 writes:{0}", i);
    }
    }
    public static void Fun2()
    {
    for (int i = 1000; i >= 6; i--)
    {
    Console.WriteLine("Fun2 writes:{0}", i);
    }
    }

    }


  3. #3
    کاربر دائمی آواتار m2011kh
    تاریخ عضویت
    فروردین 1390
    محل زندگی
    (Zweifall (Nordrhein-Westfalen
    پست
    646

    نقل قول: مشکل ارسال Reference اشیاء بین دو thread

    نقل قول نوشته شده توسط kamiloted مشاهده تاپیک
    امیدوارم به دردت بخوره.


    typedef struct
    {
    double *a;
    double *b;
    double sum;
    int veclen;
    } DOTDATA;

    /* Define globally accessible variables and a mutex */

    #define NUMTHRDS 4
    #define VECLEN 100

    DOTDATA dotstr; //GLOBAL DATA which is going to be accessed by different threads

    pthread_t callThd[NUMTHRDS];
    pthread_mutex_t mutexsum;

    void *dotprod(void *arg)
    {

    /* Define and use local variables for convenience */

    int i, start, end, len ;
    long offset;
    double mysum, *x, *y;
    offset = (long)arg;

    len = dotstr.veclen;
    start = offset*len;
    end = start + len;
    x = dotstr.a;
    y = dotstr.b;

    /*
    Perform the dot product and assign result
    to the appropriate variable in the structure.
    */

    mysum = 0;
    for (i=start; i<end ; i++)
    {
    mysum += (x[i] * y[i]);
    }

    /*
    Lock a mutex prior to updating the value in the shared
    structure, and unlock it upon updating.
    */
    pthread_mutex_lock (&mutexsum);
    dotstr.sum += mysum;
    pthread_mutex_unlock (&mutexsum);

    pthread_exit((void*) 0);
    }

    int main (int argc, char *argv[])
    {
    long i;
    double *a, *b;
    void *status;

    /* Assign storage and initialize values */
    a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
    b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));

    for (i=0; i<VECLEN*NUMTHRDS; i++)
    {
    a[i]=1.0;
    b[i]=a[i];
    }

    dotstr.veclen = VECLEN;
    dotstr.a = a;
    dotstr.b = b;
    dotstr.sum=0;

    pthread_mutex_init(&mutexsum, NULL);

    for(i=0; i<NUMTHRDS; i++)
    {
    /*
    Each thread works on a different set of data.
    The offset is specified by 'i'. The size of
    the data for each thread is indicated by VECLEN.
    */
    pthread_create(&callThd[i], NULL, dotprod, (void *)i);
    }

    /* Wait on the other threads */
    for(i=0; i<NUMTHRDS; i++)
    {
    pthread_join(callThd[i], &status);
    }

    printf ("Sum = %f \n", dotstr.sum);
    free (a);
    free (b);
    pthread_mutex_destroy(&mutexsum);
    pthread_exit(NULL);//No need of pthread_join() if pthread_exit() used.
    }







    class Program
    {
    static void Main()
    {
    Thread FirstThread = new Thread(new ThreadStart(Fun1));
    Thread SecondThread = new Thread(new ThreadStart(Fun2));
    FirstThread.Start();
    SecondThread.Start();


    }
    public static void Fun1()
    {
    for (int i = 1; i <= 1000; i++)
    {
    Console.WriteLine("Fun1 writes:{0}", i);
    }
    }
    public static void Fun2()
    {
    for (int i = 1000; i >= 6; i--)
    {
    Console.WriteLine("Fun2 writes:{0}", i);
    }
    }

    }

    سلام دوست عزیز و ممنونم از پاسختون.

    کد اولی کد C++‎ هست و متأسفانه به کار من در کل نمیاد.

    و کد دومی حس میکنم که بنده سوالم رو کمی بد مطرح کرده بودم. الان سعی میکنم که به روش بهتری سوالم رو دوباره تشریح کنم.

    این مشکل زمانی اتفاق افتاد که من یک پروژه ای داشتم که باید چهار Picturebox رو همزان با سرعت های رندوم به سمتی حرکت میدادم. این پروسه از چند لایه رد میشه.اول رفرنسی از هر PictureBox به یه کلاس دیگه فرستاده میشه و اونجا سرعت و یک معیار تغییر سرعت تصادفی تعیین میشه و بعد این تابع چهار تا نخ به اضای هر PictureBox میسازه و استارت میکنه. ارور زمانی اتفاق می افته که تابعٍ آخرین کلاسی که رفرنس PictureBoxهارو دریافت میکنه میخواد PicuteBox رو به وسیله ی رفرنسی که دریافت کرده حرکت بده. اینجاست که کامپایلر ارور میده که PictureBox ها کلاسی از یک نخ دیگه هستن و این نخ نمیتونه به اونها دسترسی داشته باشه.

    سوال من در واقع حل این مشکل بود.

    ولی باز هم ممنون از پاسختون.

    موفقو سربلند باشید.

  4. #4

    نقل قول: مشکل ارسال Reference اشیاء بین دو thread

    نقل قول نوشته شده توسط m2011kh مشاهده تاپیک
    سلام دوست عزیز و ممنونم از پاسختون.

    کد اولی کد C++‎‎ هست و متأسفانه به کار من در کل نمیاد.

    و کد دومی حس میکنم که بنده سوالم رو کمی بد مطرح کرده بودم. الان سعی میکنم که به روش بهتری سوالم رو دوباره تشریح کنم.

    این مشکل زمانی اتفاق افتاد که من یک پروژه ای داشتم که باید چهار Picturebox رو همزان با سرعت های رندوم به سمتی حرکت میدادم. این پروسه از چند لایه رد میشه.اول رفرنسی از هر PictureBox به یه کلاس دیگه فرستاده میشه و اونجا سرعت و یک معیار تغییر سرعت تصادفی تعیین میشه و بعد این تابع چهار تا نخ به اضای هر PictureBox میسازه و استارت میکنه. ارور زمانی اتفاق می افته که تابعٍ آخرین کلاسی که رفرنس PictureBoxهارو دریافت میکنه میخواد PicuteBox رو به وسیله ی رفرنسی که دریافت کرده حرکت بده. اینجاست که کامپایلر ارور میده که PictureBox ها کلاسی از یک نخ دیگه هستن و این نخ نمیتونه به اونها دسترسی داشته باشه.

    سوال من در واقع حل این مشکل بود.

    ولی باز هم ممنون از پاسختون.

    موفقو سربلند باشید.
    دریافت شد.
    کد اول برای سی بود.
    یه نمونه براتون مینویسم تا فردا براتون میزارم.موفق باشید.

  5. #5
    کاربر دائمی آواتار m2011kh
    تاریخ عضویت
    فروردین 1390
    محل زندگی
    (Zweifall (Nordrhein-Westfalen
    پست
    646

    Post نقل قول: مشکل ارسال Reference اشیاء بین دو thread

    سلام و خسته نباشید دوستان.

    دوستان که این تایپیک رو بی جواب گذاشتن ولی چون خودم پاسخ رو پیدا کردم اینجا میزارم که اگه بعدا کسی به این مشکل برخورد بتونه جواب سوال رو اینجا پیدا کنه.

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

    فرم 1 توی نخ0 در حال اجرا هست و فرم یک یک تکست باکس داره.

    کلاس 1 توی نخ1 در حال اجرا هست و میخواد به تکست باکس فرم 1 دسترسی داشته باشه. این در حالت عادی و یک خطای استثناء تولید میکنه.


    راه حل:

    در واقع باید دستوری که در شیء که در نخ دیگری هست رو به خودش بدیم که برامون انجام بده در نخ خودش. در مثال بالا باید کلاس 1 دستور رو به نخ0 منتقل کنه تا اونجا اجرا بشه.

    و این برای کنترل ها بوسیله تابع BeginInvoke قابل انجام هست که البته به عنوان پارامتر به یک Delegate از کدی که به نخ مقصد میخواید بفرستید نیاز داره. از این تابع برای بروز رسانی کنترل های فرم از نخ های دیگر استفاده میشه ولی در کل به ابزار dispatcher گفته میشه که به غیر از این کاربرد، کاربرد های زیادی داره در مورد برنامه نویسی چند نخی.

    یه مثال کوچیگی که نوشتم برای درک بهتر:

    کد فرم:
    namespace Test_Dispetcher
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
    testerKlasse tst = new testerKlasse();
    Thread testthread = new Thread(delegate() { tst.MMD(textBox1); });
    testthread.Start();
    }
    }
    }




    کد کلاسی که تابعی در اون به عنوان نخ جدید اجرا میشه:


    namespace Test_Dispetcher
    {
    class testerKlasse
    {
    public delegate void del();
    public void MMD(TextBox testTextBox)
    {
    TextBox tstTextBox = testTextBox;
    del meindel = new del(delegate() {tstTextBox.Text = "SSS";});


    tstTextBox.BeginInvoke(meindel);
    }
    }
    }


    امیدوارم که برای دوستان مفید واقع بشه.


    موفق و سربلند باشید.
    M.M.D

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

  1. مشکل در ارتباط بین دو Thread
    نوشته شده توسط Reza_Yarahmadi در بخش C#‎‎
    پاسخ: 13
    آخرین پست: دوشنبه 03 آبان 1389, 09:50 صبح
  2. مشکل در انتقال اطلاعات بین دو فرم ویندوزی
    نوشته شده توسط jas1387 در بخش C#‎‎
    پاسخ: 7
    آخرین پست: شنبه 09 خرداد 1388, 20:41 عصر
  3. ارتباط بین دو thread
    نوشته شده توسط AmirAlimadadi در بخش C#‎‎
    پاسخ: 1
    آخرین پست: شنبه 29 فروردین 1388, 11:20 صبح
  4. یک مشکل عجیب در ارتباط بین دو فرم
    نوشته شده توسط Hadizadeh در بخش مباحث عمومی دلفی و پاسکال
    پاسخ: 6
    آخرین پست: دوشنبه 29 مرداد 1386, 11:24 صبح
  5. مشکل در برقراری ارتباط بین دو جدول
    نوشته شده توسط saghari در بخش SQL Server
    پاسخ: 2
    آخرین پست: دوشنبه 19 دی 1384, 09:46 صبح

برچسب های این تاپیک

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

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