PDA

View Full Version : کار با thread



mtkzzzz
شنبه 21 اردیبهشت 1392, 10:02 صبح
سلام
من دو تا thread تو برنامه دارم. وقتی برنامه رو اجرا میکنم دو قسمت بدون نظم و ترتیب اجرا میشن
اگه بخوام بگم که هر کدام اجرا شد دیگری توقف کنه باید چکار کنم ؟
میدونم که باید با wait و signal نوشت اما نمیدونم چطور و سینتکسش چیه ؟

FastCode
شنبه 21 اردیبهشت 1392, 12:26 عصر
wait و signal هم میتونه این کار رو انجام بده ولی
بهتره که از Monitor.Enter و Monitor.Exit برای این مورد استفاده کنید.باز هم بستگی به کارتون داره که اگر کدتون رو اینجا بزارید بهتر میشه راهنماییتون کرد.
مثالهای خیلی زیادی برای کلاس Monitor در این سایت و سایتهای دیگه وجود داره

mtkzzzz
شنبه 21 اردیبهشت 1392, 13:47 عصر
اگه بشه میخوام با همون wait و signal بنویسم
مثال:

public partial class Form1 : Form
{
int a, b, c, d;

string s = string.Empty; // ""


Thread p1;
Thread p2;

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
a = 10; b = 5;

int i = 0;

while (i < 100)
{
p1 = new Thread(Mohasebe1);
p2 = new Thread(Mohasebe2);

p1.Start();
p2.Start();

i++;
}

p1.Abort();
p2.Abort();

MessageBox.Show(s);
}

void Mohasebe1()
{
c = a * b;

s = s + c.ToString();
}


void Mohasebe2()
{
d = a + b;

s = s + d.ToString();
}
}

_behnam_
شنبه 21 اردیبهشت 1392, 14:00 عصر
سلام. وقتی شما 2تا ترید را همزمان باهم صدا میزنید باهم اجرا میشود چرا که تریدها تقریبا واسه همیک کارند که چند پردازش رو همزمان انجام بدهند(البته در هر لحظه فقط یک پردازش انجام میشود اما طوری اولویت ها تقسیم میشند که گوییم همزمان اجرا میشوند).
حالا اگر مشکل شما این است که میخواهید اول یک ترید اجرا شود و بعد از آن ترید دیگری میتوانید
ترید دوم رو آخر متدی که در ترید اول است قرار دهید.
اگر هم مشکل شما با آبجکت ها هست و نمیخواهید که وقتی تریدی دارد روی یک متغیر یا آبجکت کار میکند ترید دیگر با آن کاری نداشته باشد میتونید از دستور Lock استفاده کنید.

FastCode
شنبه 21 اردیبهشت 1392, 15:34 عصر
این روش استفاده از ترد خیلی غلطه.
ایجاد کردن این همه ترد خیلی اشتباهه.معمولا حلقه رو داخل ترد مینویسن و نه ترد رو داخل حلقه.
و اگر حلقتون کمتر از چند ده هزار بار اجرا میشه سرعتتون با ترد فقط کم میشه

mtkzzzz
شنبه 21 اردیبهشت 1392, 20:10 عصر
ممکنه راهنمایی بفرمایید که چطور اینها به ترتیب اجرا بشن ؟

FastCode
شنبه 21 اردیبهشت 1392, 21:34 عصر
شما اصلا به ترد نیاز نداری.
در ضمن وقتی میخواهید صبر کنید ترد کارش تموم بشه باید Join کنید نه Abort

روش ۱(خیلی غلط):

public partial class Form1 : Form
{
int a, b;

string s = string.Empty; // ""
object lock_s = new object();

Thread p1;
Thread p2;

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
a = 10; b = 5;

int i = 0;

while (i < 100)
{
p1 = new Thread(Mohasebe1);
p2 = new Thread(Mohasebe2);

p1.Start();
p2.Start();

p1.Join();
p2.Join();

i++;
}

MessageBox.Show(s);
}

void Mohasebe1()
{
int c = a * b;
lock(lock_s)
s = s + c.ToString();
}


void Mohasebe2()
{
int d = a + b;
lock(lock_s)
s = s + d.ToString();
}
روش ۲(غلط):

public partial class Form1 : Form
{
int a, b;

string s = string.Empty; // ""
object lock_s = new object();

Thread p1;
Thread p2;

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
a = 10; b = 5;
p1 = new Thread(Mohasebe1);
p2 = new Thread(Mohasebe2);

p1.Start();
p2.Start();


p1.Join();
p2.Join();

MessageBox.Show(s);
}

void Mohasebe1()
{
int i = 0;
while (i < 100)
{
int c = a * b;
lock(lock_s)
s = s + c.ToString();
i++
}
}


void Mohasebe2()
{
int i = 0;
while (i < 100)
{
int d = a + b;
lock(lock_s)
s = s + d.ToString();
i++;
}
}
روش ۳(قابل قبول):

public partial class Form1 : Form
{
int a, b;

string s = string.Empty; // ""

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
a = 10; b = 5;
Mohasebe1();
Mohasebe2();
MessageBox.Show(s);
}

void Mohasebe1()
{
int i = 0;
while (i < 100)
{
int c = a * b;
s = s + c.ToString();
i++
}
}


void Mohasebe2()
{
int i = 0;
while (i < 100)
{
int d = a + b;
s = s + d.ToString();
i++;
}
}
برای روش درست انجام این عملیات بهتر هست که راجع به StringBuilder و Intel AVX و Mono.SSE تحقیق کنید.
مطالب خواندنی برای شما(سعی کردم مشابه عناوین ویکیپدیا رو براتون بنویسم):
Semaphore
Atomicity
ACID
Deadlock
SpinLock
lockless wait
ABA problem
Transaction
Plan 9
و خیلی های دیگه.
هر موردی رو که بهش علاقه مند هستید/شدید رو بگید که منابعش رو بهتون معرفی کنم.

این همی یکی در میان با AutoResetEvent:

public partial class Form1 : Form
{
int a, b;

string s = string.Empty; // ""
object lock_s = new object();

Thread p1;
Thread p2;
AutoResetEvent e1_2, e2_1;
public Form1()
{
InitializeComponent();
e1_2 = new AutoResetEvent(true);
e2_1 = new AutoResetEvent(false);
}

private void button1_Click(object sender, EventArgs e)
{
a = 10; b = 5;
p1 = new Thread(Mohasebe1);
p2 = new Thread(Mohasebe2);
p1.Start();
p2.Start();


p1.Join();
p2.Join();

MessageBox.Show(s);
}

void Mohasebe1()
{
int i = 0;
while (i < 100)
{
int c = a * b;
e1_2.WaitOne();
s = s + c.ToString();
e2_1.Set();
i++
}
}


void Mohasebe2()
{
int i = 0;
while (i < 100)
{
int d = a + b;
e2_1.WaitOne();
s = s + d.ToString();
e1_2.Set();
i++;
}
}
}

mtkzzzz
یک شنبه 22 اردیبهشت 1392, 09:20 صبح
ممنون دوست عزیز که پاسخ میدید.
اول اینکه من اینو باید با ترد بنویسم و در حالی که از ترد استفاده کردم بگم که یکی در میان کار کنه. برنامه اولی شما اینطور نیست و دو برنامه بعدی هم پشت هم چاپ میکنه.
راه حلش باید همون wait و signal باشه.

FastCode
یک شنبه 22 اردیبهشت 1392, 09:40 صبح
ممنون دوست عزیز که پاسخ میدید.
اول اینکه من اینو باید با ترد بنویسم و در حالی که از ترد استفاده کردم بگم که یکی در میان کار کنه. برنامه اولی شما اینطور نیست و دو برنامه بعدی هم پشت هم چاپ میکنه.
راه حلش باید همون wait و signal باشه.
برنامه ی ۳ پشت سر هم اجرا میکنه.
برنامه ی ۲ اگر تعداد زیاد باشه پشت سر هم اجرا نمیکنه.
برنامه ی ۱ جفت جفت اجرا میکنه.ولی ترتیب هر دو اجرا مشخص نیست
اگر میخواهید برنامه ۱ از این حالت خارج بشه باید تمام ترد های ایجاد شده رو در یک لیست نگداری کنید و بعد از پایان حلقه همه رو join کنید.

mtkzzzz
یک شنبه 22 اردیبهشت 1392, 11:32 صبح
برنامه ی ۳ پشت سر هم اجرا میکنه.
این برنامه قسمت اول را کامل چاپ و سپس قسمت دوم

برنامه ی ۲ اگر تعداد زیاد باشه پشت سر هم اجرا نمیکنه.
این هم همینطور(تالار (http://www.talarnet.com/))

برنامه ی ۱ یکی در میان اجرا میکنه.
این برنامه هم یکی در میان چاپ نمیکنه . عکس (http://www.funbees.ir/) زیر
104079

FastCode
یک شنبه 22 اردیبهشت 1392, 12:40 عصر
منظور از تعداد زیاد در برنامه ی ۲ بالای ۱۰۰۰۰ ه
پست ۹ رو هم ویرایش کردم.

mtkzzzz
دوشنبه 23 اردیبهشت 1392, 09:21 صبح
عزیز کل برنامه ها را مجدد کپی کردم و نتیجه زیر بود :
برنامه اول که یکی در میان نیست.
104122
برنامه دوم و سوم که هر کدام جدا جدا اجرا میشه
104123
من میخوام برنامه به شکل برنامه اول و یکی در میان چاپ بشه

amin_sltny
دوشنبه 23 اردیبهشت 1392, 09:37 صبح
عزیز کل برنامه ها را مجدد کپی کردم و نتیجه زیر بود :
برنامه اول که یکی در میان نیست.
104122
برنامه دوم و سوم که هر کدام جدا جدا اجرا میشه
104123
من میخوام برنامه به شکل برنامه اول و یکی در میان چاپ بشه

دوست عزیز ضمیمه ها را باز نمی کنه!!!!


من این کار را با Mutex انجام می دم!!


وب من (http://kanonportal.ir)

mtkzzzz
دوشنبه 23 اردیبهشت 1392, 13:44 عصر
دوست عزیز ضمیمه ها را باز نمی کنه!!!!
ضمیمه اولی
104135
ضمیمه دومی
104136

من این کار را با Mutex انجام می دم!!
:لبخندساده:

tooraj_azizi_1035
دوشنبه 23 اردیبهشت 1392, 21:20 عصر
می تونی دقیقاً صورت مسئله رو قرار بدی تا بدونم هدف چیه؟

mtkzzzz
سه شنبه 24 اردیبهشت 1392, 10:09 صبح
من میخوام با thread برنامه رو مدیریت کنم که یکی در میان انجام بیشه. مثلا تو دلفی دستورات wait و Signal هست ولی c# اش رو میخوام
مثلا اگه پردازه اول اجرا شد یک سیگنال به پردازه بعدی بفرسته و خودش wait بشه و بعکس.

tooraj_azizi_1035
سه شنبه 24 اردیبهشت 1392, 10:35 صبح
این راه حلی هست که شما ارائه دادید. لطفاً بگید خروجی باید چی باشه شاید باید از روش های دیگه در چند نخی استفاده کنید.

mtkzzzz
سه شنبه 24 اردیبهشت 1392, 11:01 صبح
خروجی به ترتیب اجرا شدن دو پردازه باشه.
مثلا یکی 50 رو چاپ میکنه و یکی آندرلاین و هر کدام 100 بار
میخوام این چاپ یکی در میان باشه . مثلا تو عکس زیر یکی در میان نیست :
104170
نمونه برنامه رو تو پست 3 گذاشتم

tooraj_azizi_1035
سه شنبه 24 اردیبهشت 1392, 11:07 صبح
یک راه این هست که شما بیای با استفاده از یک متغیر مشترک کار کنی.
اگه زوج بود اولی اجرا شه و اگه فرد دومی.
این برنامه سناریوی Producer/Consumer هست یعنی تولید کننده / مصرف کننده. 2 ترد تولید می کنند و سومی که برنامه اصلی هست مصرف می کنه.
براتون ضمیمه می کنم به همراه عکس خروجی.

tooraj_azizi_1035
سه شنبه 24 اردیبهشت 1392, 13:02 عصر
Get it now:
104183

منبعی برای مطالعه:http://www.farsimsdn.somee.com/Default.aspx?id=5

FastCode
سه شنبه 24 اردیبهشت 1392, 16:02 عصر
وقتی از ترد استفاده میکنید نباید انتظار داشته باشید نتایج یکی در میان باشه.راجع به این موارد جست و جو کنید:
time slice
jiffy
Scheduler
CFS
niceness