کسی کار با threadها رو در c++ بلده؟

mig123

New Member
با سلام. من یه لیست سراسری دارم که توسط چندترد قابل دسترسی هست. می خوام در صورتی که شرطیکه گذاشتم برای هر کدوم از تردها برقرار بود بتونه اون عنصر موردنظرش رو از لیست حذف کنه. چطوی از mutex استفاده کنم تا بقیه همزمان حذفی از لیست نداشته باشن. بدجوری گیر کردم تو برنامه.:-?
کد:
 [FONT=&quot]List<int> l;// public[/FONT]
  [FONT=&quot]For each thread[/FONT]
  [FONT=&quot]Int x;[/FONT]
  [FONT=&quot]For( it=l.begin(); it!=l.end();it++)[/FONT]
  [FONT=&quot]{[/FONT]
  [FONT=&quot]If( *it == x)[/FONT]
  [FONT=&quot]{[/FONT]
  [FONT=&quot]      Thread_mutex_lock();[/FONT]
  [FONT=&quot]      it=l.erase(it);[/FONT]
  [FONT=&quot]Thread_mutex_unlock();[/FONT]
  [FONT=&quot] [/FONT]
  [FONT=&quot]} [/FONT]
  [FONT=&quot]}[/FONT]
 

the_king

مدیرکل انجمن
با سلام. من یه لیست سراسری دارم که توسط چندترد قابل دسترسی هست. می خوام در صورتی که شرطیکه گذاشتم برای هر کدوم از تردها برقرار بود بتونه اون عنصر موردنظرش رو از لیست حذف کنه. چطوی از mutex استفاده کنم تا بقیه همزمان حذفی از لیست نداشته باشن. بدجوری گیر کردم تو برنامه.:-?
از کدوم کامپایلر و سیستم عامل استفاده می کنید؟

خود List یک منبع مشترکه، اگه یک Thread در حال پیمایش کردن List باشه و Thread دیگری همون موقع عنصری که
Thread قبلی می خواد پیمایش بکنه حذف کنه تداخل پیش میاد. کل بخش پیمایش List رو در ناحیه بحرانی قرار بدید :

کد:
List<int> l;// public
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
.
.
.
//For each thread
int x;
pthread_mutex_lock(&mut);
for(it = l.begin(); it != l.end(); it++)
{
    If (*it == x)
    {
        it = l.erase(it);
    }
}
pthread_mutex_unlock(&mut);
 

mig123

New Member
خیلی ازتون ممنونم،
من از زبان محیط vc++ و ویندوز استفاده میکنم. من کد رو به صورت دستی نوشتم. می خواستم ببینم این دستورات برای ایجاد و استفاده از تردها در ویندوز قابل استفاده هستند؟
 

the_king

مدیرکل انجمن
خیلی ازتون ممنونم،
من از زبان محیط vc++ و ویندوز استفاده میکنم. من کد رو به صورت دستی نوشتم. می خواستم ببینم این دستورات برای ایجاد و استفاده از تردها در ویندوز قابل استفاده هستند؟

نه، کدی که نوشته بودم برای کامپایلر gcc و سیستم عامل لینوکس است.

در ویندوز برای ساختن mutex از توابع API ویندوز استفاده کنید :
کد:
	list <int> l;
	HANDLE mut = CreateMutex(0, 0, 0);
.	
.	
.
	int x;
	list<int>::iterator it;
	WaitForSingleObject(mut, INFINITE);
	for(it = l.begin(); it != l.end(); it++)
	{
		if (*it == x)
		{
			it = l.erase(it);
		}
	}
	ReleaseMutex(mut);
 

mig123

New Member
خدا بهتون عوض خیر بده! اگه براتون ممکنه به این سوال من جواب بدید.
من می خوام ترد اصلی تا زمانی که کار تردهایی که ایجاد کرده خاتمه پیدا نکرده ادامه کارشو از سر نگیره. من بعد از ایجاد تردها، قبل از اینکه ترد اصلی ادامه کارشو بخواد انجام بده این دستور رو نوشتم که شما گفتید مال دستورات لینوکسه. نمی دونم به جاش چی بنویسم
کد:
// in each creadted thread
.
.
pthread_exit(0);


// in the main Thread
.
.
.
 for( cnt=0; cnt<k; cnt++)
  Pthread_join(p_thread[cnt],Null);
.
.
 
آخرین ویرایش:

the_king

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

برای ساختن Thread ها اول براشون تابعی بسازید که به محض ایجاد شدن اجرایش کنند، پارامتر n هر چیزی است
که شما دلتان بخواد به تابع ارسال کنید :
کد:
DWORD APIENTRY ThreadProc(void* n)
{
.
.
.
	return 0;
}
دقت کنید که هر زمانی که return 0 اجرا شد، Thread خاتمه می یابد، پس نیازی به تابع ()ExitThread نخواهد داشت.

برای ساختن Thread از تابع CreateThread استفاده کنید، در مثال زیر پارامتر 123 به تابع ThreadProc ارسال شده :
کد:
	HANDLE t = CreateThread(0, 0, ThreadProc, (void *)123, 0, 0);

برای تابع Pthread_join معادل خاصی وجود ندارد، یک تابعی به اسم WaitForThread بسازید :
کد:
void WaitForThread(HANDLE t)
{
	DWORD r;
	do
	{		
		GetExitCodeThread(t, &r);
	} while (r == 0x103);
}
این تابع تا زمانی که Thread مورد نظر (پارامتر ورودی اش) در حال اجرا است در داخل حلقه do while منتظر می ماند.

اگر خواستید یک Thread (چه Thread اصلی برنامه و چه Thread ای که خودتان می سازید) را از داخل خودش مدتی
معطل کنید از تابع Sleep کمک بگیرید، واحد تاخیر زمانی میلی ثانیه است، مثلا این Thread به مدت 3 ثانیه معطل شود :
کد:
	Sleep(3000);

در مثال زیر ما 3 عدد Thread می سازیم که با وقفه های زمانی متفاوتی ایجاد می شوند و بعد از مدتی خاتمه می یابند.
Thread اصلی برنامه تا زمانی که سه تایشان خاتمه نیافته اند منتظر می ماند :
کد:
// Mutex.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <iostream>

using namespace std;

void WaitForThread(HANDLE t)
{
	DWORD r;
	do
	{		
		GetExitCodeThread(t, &r);
	} while (r == 0x103);
}

DWORD APIENTRY ThreadProc(void* n)
{
	cout << endl << "Start Thread #" << (int)n << endl;
	Sleep(3000);
	cout << endl << "Finish Thread #" << (int)n << endl;
	return 0;
}

int main()
{
	HANDLE t1 = CreateThread(0, 0, ThreadProc, (void *)1, 0, 0);
	Sleep(1000);
	HANDLE t2 = CreateThread(0, 0, ThreadProc, (void *)2, 0, 0);
	Sleep(5000);
	HANDLE t3 = CreateThread(0, 0, ThreadProc, (void *)3, 0, 0);
	WaitForThread(t1);
	WaitForThread(t2);
	WaitForThread(t3);
	cout << endl << "Finish Process." << endl;
	return 0;
}

نمونه فایل اجرایی exe برنامه : Mutex.zip
 

پیوست ها

  • Mutex.zip
    46.5 کیلوبایت · بازدیدها: 2

mig123

New Member
مدیر عزیز خیلی ممنون! ببخشید که اینقدر سوال میپرسم. اگه ممکنه بفرماید که چطور برداری از تردها رو ایجاد کنم
من قبلا با beginThread برداری از تردها رو ایجاد کرده بودم، به جز این روش راه دیگه ای هم هست؟


کد:
 [FONT=&quot]vector<HANDLE>threadHandles(30);[/FONT]
  
.
.
.

 [COLOR=blue][FONT=&quot]for[/FONT][/COLOR][FONT=&quot]( [COLOR=blue]int[/COLOR] i=0;i<30;i++)[/FONT]
  [FONT=&quot]      {[/FONT]
  [FONT=&quot]            uintptr_t result=_beginthread(Thread,0,([COLOR=blue]void[/COLOR]*)i);[/FONT]
  [FONT=&quot]            [COLOR=green]//aThread[i]=(HANDLE)_beginthread(Thread,0,(void*)i);[/COLOR][/FONT]
  [FONT=&quot]            threadHandles[i]=(HANDLE)result;[/FONT]
  [FONT=&quot]      }[/FONT]
 

the_king

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

یکسری کلاس های آماده هم هست، اما در نهایت همون دو روشه، یا بصورت مستقیم از توابع API استفاده کنید
یا از توابع خود زبان.

مشکلی برای استفاده از vector نخواهید داشت، هم beginthread_ و هم CreateThread مقداری که بر می گردانند
یک HANDLE است و از این جهت فرقی ندارند. پس مشکلی برای استفاده از vector نیست.
فرق اصلی beginthread_ و CreateThread در این است که CreateThread چون جزو توابع ویندوزه، توابعی رو
بکار می گیره که بصورت stdcall__ یا همون WINAPI یا APIENTRY تعریف شوند، بنا بر این موقع تعریف کردن تابع
باید از stdcall__ یا WINAPI یا APIENTRY استفاده بشه.

اما beginthread_ جزو توابع زبان ++C است و با توابع cdecl__ که پیشفرض زبان هم هست کار می کند.
پس اگر خواستید تابع Thread را با beginthread_ بکار ببرید نباید APIENTRY را در تعریف تابع بنویسید، می توانید صریحا
cdecl__ را در تعریف تابع بنویسید اما چون پیشفرض است نیازی نیست.

در هر دو حالت Handle اون Thread ها رو یه جایی ذخیره خواهید کرد که می تواند آرایه یا vector یا هر نوع ساختار
دیگری باشد.

کد:
// Mutex.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <vector>
#include <list>

using namespace std;

void WaitForThread(HANDLE t)
{
	DWORD r;
	do
	{		
		GetExitCodeThread(t, &r);
	} while (r == 0x103);
}

DWORD APIENTRY ThreadProc(void* n)
{
	cout << endl << "Start Thread #" << (int)n << endl;
	Sleep(3000);
	cout << endl << "Finish Thread #" << (int)n << endl;
	return 0;
}

int main()
{
	vector <HANDLE> t;
	for (int i = 1; i <= 3; i++)
	{
		t.push_back(CreateThread(0, 0, ThreadProc, (void *)i, 0, 0));
		switch (i)
		{
		case 1:
			Sleep(1000);
			break;
		case 2:
			Sleep(5000);
			break;
		}
	}
	vector<HANDLE>::iterator it;
	for (it = t.begin(); it != t.end(); it++)
	{
		WaitForThread(*it);
	}
	cout << endl << "Finish Process." << endl;
	return 0;
}
 

mig123

New Member
با سلام و پوزش!
من روی لیست سراسری و لیست محلی که هر ترد دارد عملیات حذف عناصر مشترک رو از لیست سراسری رو باید انجام بدم. برای اینکار متدی نوشتم. که این متد رو با mutex قفل کردم اما موقع اجرای در شروع کار برنامه کرش میکنه و به صفحه ای میره که این پیام در اون ظاهر شده. لطفا راهنمایی ام کنید.
کد:
  [COLOR=green][FONT=&quot]/* These methods don't need a separate[/FONT][/COLOR]
  [COLOR=green][FONT=&quot]   wchar version. Hence they need to be compiled only once from[/FONT][/COLOR]
  [COLOR=green][FONT=&quot]   the original file */[/FONT][/COLOR]
  
  [FONT=&quot]_CRTIMP [COLOR=blue]void[/COLOR] [COLOR=blue]_cdecl[/COLOR] _CrtDbgBreak([/FONT]
  [FONT=&quot]    [COLOR=blue]void[/COLOR][/FONT]
  [FONT=&quot]    )[/FONT]
  [FONT=&quot]{[/FONT]
  [FONT=&quot]    DebugBreak();[/FONT]
  [FONT=&quot]}[/FONT]
کد برنامه :
کد:
WaitForSingleObject(mut1, INFINITE);//Lock
            Chk_cmn_nod(d, C,Path1);
        ReleaseMutex(mut1);//Unlock
 
آخرین ویرایش:

the_king

مدیرکل انجمن
با سلام و پوزش!
من روی لیست سراسری و لیست محلی که هر ترد دارد عملیات حذف عناصر مشترک رو از لیست سراسری رو باید انجام بدم. برای اینکار متدی نوشتم. که این متد رو با mutex قفل کردم اما موقع اجرای در شروع کار برنامه کرش میکنه و به صفحه ای میره که این پیام در اون ظاهر شده. لطفا راهنمایی ام کنید.
برای چه منظوری از DebugBreak استفاده کردید؟ معمولا برنامه های چند نخی رو مستقیما در محیط IDE متوقف
نمی کنند. امکانات دیباگر مناسب همچین مواردی نیست.
 

mig123

New Member
سلام، برنامه خطا میداد خواستم ببینم چرا. پس چطور خطایابی کنم؟ break point ها رو که برمیدارم خطا میده.نمی دونم کی و چرا این اتفاق میفته. روی کاغذ همه رو چک کردم. یا خطایی که عکسشو گذاشتم میده یا خطای با پیام زیر

Unhandled exception at 0x00417856 in KDLA.exe: 0xC0000005: Access violation reading location 0xfeeeff0e.

aspwugpp0bknv1991o1.jpg

 
آخرین ویرایش:

the_king

مدیرکل انجمن
سلام، برنامه خطا میداد خواستم ببینم چرا. پس چطور خطایابی کنم؟ break point ها رو که برمیدارم خطا میده.نمی دونم کی و چرا این اتفاق میفته. روی کاغذ همه رو چک کردم. یا خطایی که عکسشو گذاشتم میده یا خطای با پیام زیر

Unhandled exception at 0x00417856 in KDLA.exe: 0xC0000005: Access violation reading location 0xfeeeff0e.

aspwugpp0bknv1991o1.jpg


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

mig123

New Member
سلام آقای مدیر، من تا جایی که ممکن بود ناحیه بحرانی رو چک کردم اما همش خطا میده و کرش میکنه. Break point ها رو هم برداشتم اما اون خطای صفحه قبل رو باز میده.
لطفا کمکم کنید باید تا شنبه تحویلش بدم.

ببخشید میشه من کدم رو بذارم نگاه کنید؟
 

the_king

مدیرکل انجمن
سلام آقای مدیر، من تا جایی که ممکن بود ناحیه بحرانی رو چک کردم اما همش خطا میده و کرش میکنه. Break point ها رو هم برداشتم اما اون خطای صفحه قبل رو باز میده.
لطفا کمکم کنید باید تا شنبه تحویلش بدم.

ببخشید میشه من کدم رو بذارم نگاه کنید؟

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

mig123

New Member
دست شما درد نکنه. من یه توضیح دربارش می نویسم و دو تابع اصلی رو با توضیحات اینجا می ذارم. خیلی به من لطف می کنید.
 

mig123

New Member
[FONT=&quot]سلام، کل برنامه رو پایین پیوست کردم. لطفا کمک کنید.

عناصر مشترک بین تردها
[/FONT]
[FONT=&quot]1. [FONT=&quot]لیست های سراسری[/FONT][FONT=&quot]SR[/FONT][FONT=&quot] و [/FONT][FONT=&quot]Path[/FONT][/FONT]
[FONT=&quot]2. [FONT=&quot]بردار سراسری [/FONT][FONT=&quot]Chkd[/FONT][/FONT]
[FONT=&quot]3. [FONT=&quot]شی [/FONT][FONT=&quot]d[/FONT][FONT=&quot] از کلاس [/FONT][FONT=&quot]DLA[/FONT][/FONT]
[FONT=&quot]4. [FONT=&quot]متغیرهای [/FONT][FONT=&quot]n, a, b, Best_size[/FONT][/FONT]

[FONT=&quot]تابعی که تردها آن را فراخوانی می کنند و نکات آن :[/FONT]
[FONT=&quot]1. [FONT=&quot]تابع [/FONT][FONT=&quot]ThreadProc[/FONT][FONT=&quot]: در این تابع تا زمانی که لیست سراسری [/FONT][FONT=&quot]SR[/FONT][FONT=&quot] تهی نشود، در داخل حلقه [/FONT][FONT=&quot]do…While[/FONT][FONT=&quot] تابع [/FONT][FONT=&quot]Chk_cmn_nod[/FONT][FONT=&quot] را فراخوانی می کند. این تابع لیست سراسری [/FONT][FONT=&quot]SR[/FONT][FONT=&quot] را با لیستی که[/FONT][FONT=&quot]عنصر خانه [/FONT][FONT=&quot]C[/FONT][FONT=&quot] ام شی [/FONT][FONT=&quot]d[/FONT][FONT=&quot] دارد، بررسی میکند و بعد عناصر مشترک را ( در صورت یافتن ) از لیست سراسری [/FONT][FONT=&quot]SR[/FONT][FONT=&quot] حذف می کند.[/FONT][/FONT]

[FONT=&quot]2. [FONT=&quot]هر ترد به محض اینکه لیست [/FONT][FONT=&quot]SR[/FONT][FONT=&quot] را خالی دید از حلقه [/FONT][FONT=&quot]do…While[/FONT][FONT=&quot] خارج می شود و ادامه کار را در تابع[/FONT][FONT=&quot]ThreadProc[/FONT][FONT=&quot] از سر می گیرد[/FONT][FONT=&quot]. در این قسمت تردها اندازه لیست سراسری[/FONT][FONT=&quot]Path[/FONT][FONT=&quot] که در تابع [/FONT][FONT=&quot]Chk_cmn_nod[/FONT][FONT=&quot] مقداردهی می شود را محاسبه کرده و در صورتی که کمتر از مقدار [/FONT][FONT=&quot]Best_size[/FONT][FONT=&quot] باشد. هر ترد عناصری که در لیست [/FONT][FONT=&quot]path1[/FONT][FONT=&quot]محلی خود دارد را در نظر گرفته و در صورتی که خانه متناظر با آن در بردار سراسری [/FONT][FONT=&quot]Chkd[/FONT][FONT=&quot] صفر باشد، ان را یک کرده و تابعی را برای شی سراسری [/FONT][FONT=&quot]d[/FONT][FONT=&quot] به نام [/FONT][FONT=&quot]RewardAndPenalty[/FONT][FONT=&quot] فراخوانی می کند.[/FONT][/FONT]


کد:
کد:
[SIZE=2][COLOR=blue][FONT=&quot]void[/FONT][/COLOR][/SIZE][FONT=&quot][SIZE=2] Chk_cmn_nod(DLA d, [COLOR=blue]int[/COLOR] c, list<[COLOR=blue]int[/COLOR]>Path1)[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]{[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      list <[COLOR=blue]int[/COLOR]>  ::iterator it1;[COLOR=green]//vector[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      list <Action> ::iterator it2;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      cout<<[COLOR=#A31515]" Test"[/COLOR]<<c<<[COLOR=#A31515]"---"[/COLOR];[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      list<[COLOR=blue]int[/COLOR]> tmp, tmp1 ;list<[COLOR=blue]int[/COLOR]>::iterator last, itr1, itr2;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      [COLOR=blue]int[/COLOR] flag=0;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      [COLOR=blue]try[/COLOR]{[/SIZE][/FONT][SIZE=2]
  [/SIZE][SIZE=2][COLOR=blue][FONT=&quot]for[/FONT][/COLOR][/SIZE][FONT=&quot][SIZE=2](it2=d.dla.at(c).actions.actionList.begin();it2!=d.dla.at(c).actions.actionList.end();it2++)[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]                  tmp.push_back(it2->getId());[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]                  SR.sort();[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  tmp.sort();[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]      list<[COLOR=blue]int[/COLOR]> l3(tmp.size() + SR.size(), 0);[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]last = set_intersection ( tmp.begin ( ) , tmp.end ( ) ,SR.begin ( ) , SR.end ( ) , l3.begin ( ) );[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]      [COLOR=blue]for[/COLOR](itr1=l3.begin();itr1!= last; itr1++)[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  SR.remove(*itr1); [COLOR=#00B050]// change public list[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  flag=1;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            }[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      }[COLOR=blue]catch[/COLOR](...)[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            cout<[COLOR=#A31515]"Error"[/COLOR];[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      }[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  [COLOR=blue]if[/COLOR] (flag==1)[COLOR=#00B050]// if finds common nodes into boath list[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        tmp1=Path1;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        Path.merge(tmp1); [COLOR=#00B050]// change public list[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  }[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]}[/SIZE][/FONT][SIZE=2]
  [/SIZE][SIZE=2][COLOR=blue][FONT=&quot]//-------------------------------------[/FONT][/COLOR][/SIZE][SIZE=2]
  [/SIZE][SIZE=2][COLOR=blue][FONT=&quot]//-------------------------------------[/FONT][/COLOR][/SIZE][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]DWORD APIENTRY ThreadProc([COLOR=blue]void[/COLOR]* prm)[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]{     [/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      d.DLAinitialList(n,a,b);[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      [COLOR=blue]int[/COLOR] C,N,P=0;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      C=([COLOR=blue]int[/COLOR])prm;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      list<[COLOR=blue]int[/COLOR]>Path1,Tmp_Path;[COLOR=#00B050]// local list[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      list<[COLOR=blue]int[/COLOR]>::iterator t;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      Path1.push_back(C);[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]      [COLOR=blue]do[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            WaitForSingleObject(mut1, INFINITE);[COLOR=green]//Lock[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  Chk_cmn_nod(d, C,Path1);[COLOR=#00B050]// change public list[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            ReleaseMutex(mut1);[COLOR=green]//Unlock[/COLOR][/SIZE][/FONT][SIZE=2]
  
  
  [/SIZE][FONT=&quot][SIZE=2]            WaitForSingleObject(mut4, INFINITE);[COLOR=green]//Lock[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  d.dla.at(C).actions.Remove(P);[COLOR=#00B050]// change public object[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  d.dla.at(C).actions.setNewProb();[COLOR=#00B050]//change public object[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  N=d.dla.at(C).selectRandomAct();[COLOR=#00B050]//change public object[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            ReleaseMutex(mut4);[COLOR=green]//Unlock[/COLOR][/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]            [COLOR=blue]if[/COLOR](!SR.empty())  Path1.push_back(N);[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            P=C;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            C=N;[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]      }[COLOR=blue]while[/COLOR](!SR.empty());[/SIZE][/FONT][SIZE=2]
  
  
  
  [/SIZE][FONT=&quot][SIZE=2]      Tmp_Path=Path;[COLOR=#00B050]// read public list[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      Tmp_Path.sort();[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      Tmp_Path.unique();[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]      [COLOR=blue]if[/COLOR](Tmp_Path.size() < Best_size)[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            t=Path1.begin();[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            [COLOR=blue]for[/COLOR]([COLOR=blue]int[/COLOR] i=0;i<Path1.size();i++)[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  [COLOR=blue]int[/COLOR] x= *t;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  [COLOR=blue]int[/COLOR] y=*(++t);[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]                  WaitForSingleObject(mut2, INFINITE);[COLOR=#00B050]//lock[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        cout<[COLOR=#A31515]"r"[/COLOR];[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        [COLOR=blue]if[/COLOR](Chkd.at(y)==0)[COLOR=#00B050]//check public vector[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                              Chkd.at(y)=1;[COLOR=#00B050]//change[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                              d.dla.at(x).RewardAndPenalty(y,0);[COLOR=#00B050] //change[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        }[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  ReleaseMutex(mut2);[COLOR=#00B050]//unlock[/COLOR][/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]            }[COLOR=green]//end of for[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      }[COLOR=green]// end of if[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      [COLOR=blue]else[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            [COLOR=blue]for[/COLOR]([COLOR=blue]int[/COLOR] i=0;i<Path1.size();i++)[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  [COLOR=blue]int[/COLOR] x= *t;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  [COLOR=blue]int[/COLOR] y=*(++t);[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  WaitForSingleObject(mut3, INFINITE);[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        cout<[COLOR=#A31515]"p"[/COLOR];   [/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        [COLOR=blue]if[/COLOR](Chkd.at(y)==0)[COLOR=#00B050] //check public vector[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        {[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                              Chkd.at(y)=1;[COLOR=#00B050] //change[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                              d.dla.at(x).RewardAndPenalty(y,1);[COLOR=#00B050] //change[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        }[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                  ReleaseMutex(mut3);[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]            }[COLOR=green]//end of for[/COLOR][/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]      }[COLOR=green]// end of else[/COLOR][/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]      WaitForSingleObject(mut5, INFINITE);[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]            [COLOR=blue]for[/COLOR](t=Path1.begin();t!=Path1.end();t++)[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]                        d.dla.at(*t).actions.Merge();[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]            ReleaseMutex(mut5);[/SIZE][/FONT][SIZE=2]
  
  [/SIZE][FONT=&quot][SIZE=2]      [COLOR=blue]return[/COLOR] 0;[/SIZE][/FONT][SIZE=2]
  [/SIZE][FONT=&quot][SIZE=2]}[/SIZE][/FONT][SIZE=2]
  
[/SIZE]
 

پیوست ها

  • code.zip
    4.1 کیلوبایت · بازدیدها: 2
آخرین ویرایش:

the_king

مدیرکل انجمن
نمی دونم دقیقا چیکار می کنه یا قراره که بکنه، اما به هر حال بعد از ویرایش کردنش الان اجرا میشه : KDLA.zip
 

پیوست ها

  • KDLA.zip
    76.9 کیلوبایت · بازدیدها: 4

mig123

New Member
سلام،
مدیر جان برنامه کار نمی کنه. تو این قسمت شما چرا return 0 گذاشتید؟
من یه دستور cout که برای تستش داخل حلقه do نوشتم رو اجرا نمیکنه. با اینکه به تابع Chk_cmn_nod لیست Path1 رو پاس می دم اما برای همه مقدارش صفره.
تو همین تابع ThreadProc من هرچی دستور قبل از do می نویسم نمی تونه اجراش کنه در حالیکه می پره دستور تابعی که تو chk_cmn-nod هست رو اجرا میکنه. لطفا منو دریابید.


کد:
 [FONT=&quot] [/FONT]
  [FONT=&quot]DWORD APIENTRY ThreadProc([COLOR=blue]void[/COLOR]* prm)[/FONT]
  [FONT=&quot]{     [/FONT]
  [FONT=&quot]      d.DLAinitialList(n, a, b);[/FONT]
  [FONT=&quot]      [COLOR=blue]return[/COLOR] 0;[COLOR=#00B050]//?????[/COLOR][/FONT]
  [FONT=&quot]      [COLOR=blue]int[/COLOR] C, N, P = 0, isSREmpty;[/FONT]
  [FONT=&quot]      C = ([COLOR=blue]int[/COLOR])prm;[/FONT]
  [FONT=&quot]      list<[COLOR=blue]int[/COLOR]> Path1, Tmp_Path;[/FONT]
  [FONT=&quot]      list<[COLOR=blue]int[/COLOR]>::iterator t;[/FONT]
  [FONT=&quot]      Path1.push_back(C);[/FONT]
  [FONT=&quot]      [/FONT]
  [FONT=&quot] [/FONT]
  [FONT=&quot]      [COLOR=blue]do[/COLOR][/FONT]
  [FONT=&quot]      {[/FONT]
  [FONT=&quot]            WaitForSingleObject(mut1, INFINITE);[COLOR=green]//Lock[/COLOR][/FONT]
  [FONT=&quot]            cout<<[COLOR=#A31515]"size"[/COLOR]<<Path1.size();[COLOR=#00B050]// for test[/COLOR][/FONT]
  [FONT=&quot]            Chk_cmn_nod(d, C, Path1);[/FONT]
  [FONT=&quot]            ReleaseMutex(mut1);[COLOR=green]//Unlock[/COLOR][/FONT]
  [FONT=&quot]            WaitForSingleObject(mut2, INFINITE);[COLOR=green]//Lock[/COLOR][/FONT]
  [FONT=&quot]            d.dla.at(C).actions.Remove(P);[/FONT]
  [FONT=&quot]            d.dla.at(C).actions.setNewProb();[/FONT]
  [FONT=&quot]            N = d.dla.at(C).selectRandomAct();[/FONT]
  [FONT=&quot]            ReleaseMutex(mut2);[COLOR=green]//Unlock[/COLOR][/FONT]
  [FONT=&quot]            WaitForSingleObject(mut6, INFINITE);[COLOR=green]//Lock            [/COLOR][/FONT]
  [FONT=&quot]            [COLOR=blue]if[/COLOR] (SR.empty())[/FONT]
  [FONT=&quot]                  isSREmpty = 1;[/FONT]
  [FONT=&quot]            [COLOR=blue]else[/COLOR][/FONT]
  [FONT=&quot]            {[/FONT]
  [FONT=&quot]                  isSREmpty = 0;          [/FONT]
  [FONT=&quot]                  Path1.push_back(N);[/FONT]
  [FONT=&quot]            }[/FONT]
  [FONT=&quot]            ReleaseMutex(mut6);[COLOR=green]//Unlock[/COLOR][/FONT]
  [FONT=&quot]            P = C;[/FONT]
  [FONT=&quot]            C = N;[/FONT]
  [FONT=&quot]      } [COLOR=blue]while[/COLOR](isSREmpty == 0);[/FONT]
  [FONT=&quot]      [COLOR=green]//WaitForSingleObject(mut2, INFINITE);//Lock[/COLOR][/FONT]
  [FONT=&quot]      Tmp_Path = Path;[/FONT]
  [FONT=&quot]      [COLOR=green]//ReleaseMutex(mut2);//Unlock[/COLOR][/FONT]
  [FONT=&quot]      Tmp_Path.sort();[/FONT]
  [FONT=&quot]      Tmp_Path.unique();[/FONT]
  [FONT=&quot]      [COLOR=blue]if[/COLOR] (Tmp_Path.size() < Best_size)[/FONT]
  [FONT=&quot]      {[/FONT]
  [FONT=&quot]            t = Path1.begin();[/FONT]
  [FONT=&quot]            [COLOR=blue]for[/COLOR] ([COLOR=blue]unsigned[/COLOR] [COLOR=blue]int[/COLOR] i = 0; i < Path1.size(); i++)[/FONT]
  [FONT=&quot]            {[/FONT]
  [FONT=&quot]                  [COLOR=blue]int[/COLOR] x = *t;[/FONT]
  [FONT=&quot]                  [COLOR=blue]int[/COLOR] y = *(++t);[/FONT]
  [FONT=&quot]                  WaitForSingleObject(mut3, INFINITE);[/FONT]
  [FONT=&quot]                  [COLOR=green]//cout << "r";[/COLOR][/FONT]
  [FONT=&quot]                  [COLOR=blue]if[/COLOR] (Chkd.at(y) == 0)[/FONT]
  [FONT=&quot]                  {[/FONT]
  [FONT=&quot]                        Chkd.at(y) = 1;[/FONT]
  [FONT=&quot]                        d.dla.at(x).RewardAndPenalty(y, 0);[/FONT]
  [FONT=&quot]                  }[/FONT]
  [FONT=&quot]                  ReleaseMutex(mut3);[/FONT]
  [FONT=&quot]            }[COLOR=green]//end of for[/COLOR][/FONT]
  [FONT=&quot]      }[COLOR=green]// end of if[/COLOR][/FONT]
  [FONT=&quot]      [COLOR=blue]else[/COLOR][/FONT]
  [FONT=&quot]      {[/FONT]
  [FONT=&quot]            [COLOR=blue]for[/COLOR] ([COLOR=blue]unsigned[/COLOR] [COLOR=blue]int[/COLOR] i = 0; i < Path1.size(); i++)[/FONT]
  [FONT=&quot]            {[/FONT]
  [FONT=&quot]                  [COLOR=blue]int[/COLOR] x = *t;[/FONT]
  [FONT=&quot]                  [COLOR=blue]int[/COLOR] y = *(++t);[/FONT]
  [FONT=&quot]                  WaitForSingleObject(mut4, INFINITE);[/FONT]
  [FONT=&quot]                  [COLOR=green]//cout << "p";    [/COLOR][/FONT]
  [FONT=&quot]                  [COLOR=blue]if[/COLOR] (Chkd.at(y) == 0)[/FONT]
  [FONT=&quot]                  {[/FONT]
  [FONT=&quot]                        Chkd.at(y) = 1;[/FONT]
  [FONT=&quot]                        d.dla.at(x).RewardAndPenalty(y, 1);[/FONT]
  [FONT=&quot]                  }[/FONT]
  [FONT=&quot]                  ReleaseMutex(mut4);[/FONT]
  [FONT=&quot]            }[COLOR=green]//end of for[/COLOR][/FONT]
  [FONT=&quot]      }[COLOR=green]// end of else[/COLOR][/FONT]
  [FONT=&quot]      WaitForSingleObject(mut5, INFINITE);[/FONT]
  [FONT=&quot]      [COLOR=blue]for[/COLOR] (t = Path1.begin(); t != Path1.end(); t++)[/FONT]
  [FONT=&quot]      {[/FONT]
  [FONT=&quot]            d.dla.at(*t).actions.Merge();[/FONT]
  [FONT=&quot]      }[/FONT]
  [FONT=&quot]      ReleaseMutex(mut5);[/FONT]
  [FONT=&quot]      [COLOR=blue]return[/COLOR] 0;[/FONT]
  [FONT=&quot]}[/FONT]
 

the_king

مدیرکل انجمن
کدتون احتمالا مشکل زیاد داره، ویرایش کردم و الان خطا در این بخشه :
کد:
			try
			{
				t++;
				if (t != Path1.end())
				{
					int y = *t;
					if (Chkd.at(y) == 0)
					{
						Chkd.at(y) = 1;
						WaitForSingleObject(mutd, INFINITE);//Lock
						d.dla.at(x).RewardAndPenalty(y, 1);
						ReleaseMutex(mutd);//Unlock
					}
				}
			}
			catch (...)
			{
				cout << "Error B" << endl;
			}

پروژه ویرایش شده : KDLA2.zip
 

پیوست ها

  • KDLA2.zip
    80.8 کیلوبایت · بازدیدها: 3

جدیدترین ارسال ها

بالا