Tam Sürümünü Görmek İçin : shared_ptr<> ve thread_specific_ptr<>
#include "stdafx.h"
using namespace std;
class E
{
public:
E(){}
};
class B
{
private:
std::vector< boost::shared_ptr<E> > e_list;
boost::thread_specific_ptr< boost::shared_ptr<E> > tss;
boost::mutex mutex_e_list;
public:
void Execute()
{
boost::shared_ptr<E> e;
boost::mutex::scoped_lock lk_th( mutex_e_list );
e.reset( new E() );
tss.reset( &e );
e_list.insert( e_list.begin(), e );
std::vector< boost::shared_ptr<E> >::iterator i;
e_list.erase( e_list.begin() );
}
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
b.Execute();
return 0;
}
Yukarıdaki kodlarda bir çalışma zamanı hatası var(shared_count.hpp, satır 141), öyle sanıyorum ki tss ile ilgili bir hata yapıyorum, ama malesefki hatamı göremiyorum.
acehreli
05/09/2005, 20:18
Kodunda bilmedigim bazi seyler var ama yine de tss'in e'den daha uzun sure yasadigini bildigimize gore, bence hata
tss.reset( &e );
satirinda olmali. tss e'nin adresini aldigina gore, daha sonradan (ornegin bozucu islevde?) onunla bir sey yapacaktir. Ama 'e' Execute'tan ciktigimiz zaman sonlaniyor.
Ali
acehreli
05/09/2005, 20:27
Simdi baktim, thread_specific_ptr'a verilen sey, void dOndUren ve void* alan bir temizlik islevi olmaliymis. Yani sunun gibi bir sey:
void temizlik_islevim(void * veri_)
{
/* bu gibi islevler icinde ilk yapilan, veri'yi kendi turumuze dOnusturmektir */
BenimTurum * veri = veri_;
/* Simdi kendi bildigim turle kendi islevimde istedigim temizligi yaparim... */
}
/* ... */
tss.reset(temizlik_islevim);
boost.org'da ornek gostermedikleri icin konuyu tam anlamadim ama bu kadarindan eminim :)
Ali
@acehreli
Öncelikle zamanınızı ayırıp benim için döküman karıştırdığınız ve bir cevap yazdığınız için teşekkür ederim.
birinci cevabınıza ilişikin;
reset işlevinin içeriği aşağıdaki şekilde
void reset(T* p=0)
{
T* cur = get();
if (cur == p) return;
delete cur;
m_tss.set(p);
}
Bu şartlar itibariyle reset işlevi bir başka değer ile ikinci kez çalıştırdığımızda
1- tss'ye verilen değer new işleciyle atanmadığı için
2- verilen değişken çokdan silinmiş olduğu için
hata oluşur, ama ben reset işlevini bütün program boyunca bir defa çağırıyorum. Bir diğer ihtimal ise, tss nin bozucu işlevi, bunu tam anlayamadım çünkü ne olduğunu bilmediğim işlevler çalıştırılmış,
//1
tss::~tss()
{
int res = 0;
res = TlsFree(m_key);
assert(res);
}
//2
tss::~tss()
{
int res = 0;
res = pthread_key_delete(m_key);
assert(res == 0);
}
//3
tss::~tss()
{
OSStatus lStatus = MPDeallocateTaskStorageIndex(m_key);
assert(lStatus == noErr);
}
acaba bu işlevlerde mi reset işlevi gibi gösterici üzerinde delete işlecini uyguluyor?( sanırım evet )
ikinci cevabına ilişkin;
bendeki kütüphaneler 1_31_0 ve tss::reset() işlevi yukarıda yazdığım gibi ve ben bundan sizin çıkardığınız mânâyı çıkaramıyorum( void temizlik_islevim(void * veri_) ) ve ben bir çalışma zamanı( sizin orda runtime diyorlar ) hatası alıyorum. Şu anda boost kütüphaneleri 1.33 versiyonunna ulaşmış bunlar üzerindede yaptığım incelemede thread_specific_ptr<>::reset() işlevinde bir değişim olmadığını farkettim.
void reset(T* p=0)
{
T* cur = get();
if (cur == p) return;
m_tss.set(p);
if (cur) m_tss.cleanup(cur);
}
acehreli
07/09/2005, 00:13
thread_specific_ptr::reset konusunda haklisin. Herhalde shared_ptr'in kurucusunda aldigi parametre ile reset islevinde aldigi parametrenin iliskisine bakarak yanlis bir cikarim yapmisim.
thread_specific_ptr durumunda is senin dedigin gibi farkli: kurucusu temizlik islevi aliyor ama reset bir nesne isaretcisi aliyor. Kisa devre yapmisim herhalde :)
Kusura bakma ama hic deneyimim yok; ama ilgimi de cekti; belki bir seyler dener ve anlamaya calisirim.
Ali
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.