PDA

View Full Version : پر شدن صف و کنترل کردن Threadها



amin_sltny
سه شنبه 14 خرداد 1392, 21:16 عصر
سلام.

میخواستم بگم من یه صف (queue) درست کردن و در اون با استفاده از چند thread مقدار وارد این صف میکنم

حالا با یه مشکلی مواجه شدم و اون هم اینه که وقتی صفم پر میشه از اطلاعات thread بعدی وارد نمیشه. و اطلاعات چندین thrad را رها میکنه

چه طوری باید این thread ها را زمانی که صف پر میشه متوقف کنم و زمانی که thread خالی میشه دوباره شروع به کار کنن؟

ممنون

us1234
سه شنبه 14 خرداد 1392, 21:47 عصر
اگه اول هر ترد پر و خالی بودن صف چک بشه فکر کنم مشکلت حل بشه.

amin_sltny
سه شنبه 14 خرداد 1392, 22:35 عصر
اگه اول هر ترد پر و خالی بودن صف چک بشه فکر کنم مشکلت حل بشه.
می دونم دوست عزیز:
اول بار چک میکنه که صف پر هست یا خالی بعد اگه پر بود باید چی کار کنه؟

us1234
سه شنبه 14 خرداد 1392, 22:39 عصر
راستش یکم فکر کردم اینکار راه حلی نداره جز اینکه از حالت تردی خارج بشه و بصورت تک روندی انجام بشه . هر روشی هم که ارائه بشه ( مثل استفاده از سمافور و ... ) عملا داری ترد ها را محدود میکنی تا به یک روند ساده برسی .

amin_sltny
سه شنبه 14 خرداد 1392, 22:41 عصر
راستش یکم فکر کردم اینکار راه حلی نداره جز اینکه از حالت تردی خارج بشه و بصورت تک روندی انجام بشه . هر روشی هم که ارائه بشه ( مثل استفاده از سمافور و ... ) عملا داری ترد ها را محدود میکنی تا به یک روند ساده برسی .

میشه بگی سمافور چیه؟

tooraj_azizi_1035
سه شنبه 14 خرداد 1392, 22:44 عصر
اگه اصرار نداری خودت بنویسی یه کلاس آماده به نام ConcurrentQueue برای این کار از قبل نوشته شده:
تمام هماهنگی ها به شکل داخلی پیاده شده. مثلاً اگه TryDequeue رو همزمان برای گرفتن مقدار از صف صدار بزنن هیچکدوم بلوک نمیشن. در صورت کشف یک تداخل یکی از دو باید سعی کنه بعداً آیتم رو برداره. تمام عملیات به شکل اتمیک انجام میشه.http://msdn.microsoft.com/en-us/library/dd267265.aspx

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

class CQ_EnqueueDequeuePeek
{
// Demonstrates:
// ConcurrentQueue<T>.Enqueue()
// ConcurrentQueue<T>.TryPeek()
// ConcurrentQueue<T>.TryDequeue()
static void Main ()
{
// Construct a ConcurrentQueue.
ConcurrentQueue<int> cq = new ConcurrentQueue<int>();

// Populate the queue.
for (int i = 0; i < 10000; i++) cq.Enqueue(i);

// Peek at the first element.
int result;
if (!cq.TryPeek(out result))
{
Console.WriteLine("CQ: TryPeek failed when it should have succeeded");
}
else if (result != 0)
{
Console.WriteLine("CQ: Expected TryPeek result of 0, got {0}", result);
}

int outerSum = 0;
// An action to consume the ConcurrentQueue.
Action action = () =>
{
int localSum = 0;
int localValue;
while (cq.TryDequeue(out localValue)) localSum += localValue;
Interlocked.Add(ref outerSum, localSum);
};

// Start 4 concurrent consuming actions.
Parallel.Invoke(action, action, action, action);

Console.WriteLine("outerSum = {0}, should be 49995000", outerSum);
}
}

amin_sltny
سه شنبه 14 خرداد 1392, 22:48 عصر
اگه اصرار نداری خودت بنویسی یه کلاس آماده به نام ConcurrentQueue برای این کار از قبل نوشته شده:
تمام هماهنگی ها به شکل داخلی پیاده شده. مثلاً اگه TryDequeue رو همزمان برای گرفتن مقدار از صف صدار بزنن هیچکدوم بلوک نمیشن. در صورت کشف یک تداخل یکی از دو باید سعی کنه بعداً آیتم رو برداره. تمام عملیات به شکل اتمیک انجام میشه.http://msdn.microsoft.com/en-us/library/dd267265.aspx

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

class CQ_EnqueueDequeuePeek
{
// Demonstrates:
// ConcurrentQueue<T>.Enqueue()
// ConcurrentQueue<T>.TryPeek()
// ConcurrentQueue<T>.TryDequeue()
static void Main ()
{
// Construct a ConcurrentQueue.
ConcurrentQueue<int> cq = new ConcurrentQueue<int>();

// Populate the queue.
for (int i = 0; i < 10000; i++) cq.Enqueue(i);

// Peek at the first element.
int result;
if (!cq.TryPeek(out result))
{
Console.WriteLine("CQ: TryPeek failed when it should have succeeded");
}
else if (result != 0)
{
Console.WriteLine("CQ: Expected TryPeek result of 0, got {0}", result);
}

int outerSum = 0;
// An action to consume the ConcurrentQueue.
Action action = () =>
{
int localSum = 0;
int localValue;
while (cq.TryDequeue(out localValue)) localSum += localValue;
Interlocked.Add(ref outerSum, localSum);
};

// Start 4 concurrent consuming actions.
Parallel.Invoke(action, action, action, action);

Console.WriteLine("outerSum = {0}, should be 49995000", outerSum);
}
}


دوست عزیز ممنونم اما من با این کلاس آشنایی داشتم ولی می خوام خودم بنویسم:قلب::لبخندساده:

us1234
سه شنبه 14 خرداد 1392, 22:49 عصر
توی برنامه نویسی همروند چندین ابزار هست که بسته به نیاز میشه از اونا استفاده کرد یکی از این ابزار ها سمافور ها هستند .
سمافور را میشه مثل یک قفل در نظر گرفت که بسته به شرایط میتونه انجام کار یک ترد را pause کنه و بعد دوباره ادامه بده
تو سی شارپ دانت 4 اینجور تعریف میشه

static SemaphoreSlim sem1 = new SemaphoreSlim(1);

ابزارهای دیگه هم هست مثل فورک ، لاک و یا پارالل فور

tooraj_azizi_1035
سه شنبه 14 خرداد 1392, 23:13 عصر
source کلاس ConcurrentQueue رو ببین:
http://www.dotnetframework.org/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/Collections/Concurrent/ConcurrentQueue@cs/1305376/ConcurrentQueue@cs

amin_sltny
چهارشنبه 15 خرداد 1392, 14:10 عصر
source کلاس ConcurrentQueue رو ببین:
http://www.dotnetframework.org/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/Collections/Concurrent/ConcurrentQueue@cs/1305376/ConcurrentQueue@cs

میشه یه توضیح کوتاه در موردش بدید اخه من از این کلاس چیزی سر در نیاوردم