最近、私は狡猾な計画を考えました(tm :P)) プログラムの設定構造を更新する必要があります (15 秒ごとに言ってみましょう)。設定構造は複数の関数によって使用され、それらの関数はすべて複数のスレッドによって呼び出されます。そのため、古い設定構造体を安全に解放できるタイミングを知るために、参照カウンターが必要です。それで、これは正しい方法ですか?コードを注意深く読まなくても大丈夫だという回答はしないでください。共有ポインタに関しては、このような悪用を行うと間違いを犯しやすくなります (私を信じてください)。編集:重要な部分について言及するのを忘れていました。updateSettings() で初期化し、再度呼び出されるまでドロップしないため (その後、myFucntion がメモリ内の 2 つの設定のもう一方を使用するため)、この実装により ref カウンターが 0 にドロップされるのを防ぐことができると思います。
#include<memory>
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
struct STNGS
{
int i;
vector<double> v;
};
static int CUR_STNG=0;
shared_ptr<STNGS> stngsArray[2];
int myFunction() //called by multiple threads
{
shared_ptr<STNGS> pStngs=stngsArray[CUR_STNG];
STNGS& stngs=*pStngs;
//do some stuff using stngs
}
void updateSettings()
{
auto newIndex=(CUR_STNG+1)%2;
stngsArray[newIndex].reset(new STNGS);
CUR_STNG=newIndex;
}
void initialize()
{
auto newIndex=CUR_STNG;
stngsArray[newIndex].reset(new STNGS);
CUR_STNG=newIndex;
}
int main()
{
initialize();
//launch bunch of threads that are calling myFunction
while(true)
{
//call updateSettings every 15 seconds
}
}
編集:コメントからのフィードバックを使用して、コードを更新しました:
#include<memory>
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
static const int N_STNG_SP=4;
static int CUR_STNG=0;
struct STNGS
{
int i;
vector<double> v;
STNGS()
{
for (int i=0;i<10;++i)
v.push_back(42);
}
};
shared_ptr<STNGS> stngs[N_STNG_SP];
int myFunction() //called by multiple threads
{
shared_ptr<STNGS> pStngs=stngs[CUR_STNG];
STNGS& stngs=*pStngs;
//do some stuff using stngs
}
void updateSettings()
{
auto pStng=new STNGS;
//fill *pStng
int newVer=(CUR_STNG+1)%N_STNG_SP;
stngs[newVer].reset(pStng);
CUR_STNG=newVer;
}
void initialize()
{
auto pStng=new STNGS;
//fill *pStng
int newVer=(CUR_STNG+1)%N_STNG_SP;
stngs[newVer].reset(pStng);
CUR_STNG=newVer;
}
int main()
{
initialize();
//launch bunch of threads that are calling myFunction
while(true)
{
//call updateSettings every 15 seconds
updateSettings();
}
}