今回は、私が遭遇した問題のいくつかを整理し、再び遭遇する学生が簡単に解決できることを願っています。また、最近ブログフィードの更新が遅れている理由も併せて解説します。
1. Linux でスレッドを作成するとメモリ リークが発生します
今日、外部ネットワーク上にサーバーを解放した後、top を使用したところ、virt の使用量が増加しており、一度に 8m ずつ増加していました。したがって、調査の結果、最終的にはメモリ リークが原因であることが判明しました。
コードは次のとおりです:
1 2 3 4 5 6 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー |
pthread_t thread_id; int ret=pthread_create(&thread_id, NULL, flush_thread_work, (void*)&m_sql_client); if(ret!=0){ APPSCORE_ERROR("Thread creation failed:%d",ret); return ret; } ログイン後にコピー |
flash_thread_work 関数内:
1 2 3 4 5 ログイン後にコピー ログイン後にコピー ログイン後にコピー |
void* flush_thread_work(void* args) { //....do something return NULL; } ログイン後にコピー |
コード内でスレッドが開始された後、メイン プロセスは実行を継続し、新しいスレッドをそのままにしておきます (thread_join は呼び出されません)。メイン プロセスは、データを処理するために時々そのようなスレッドを呼び出します。着陸。
この書き方では実際にメモリリークが発生します。
この問題は Linux の man ページで説明されています:
結合可能なスレッドが終了すると、別のスレッドがそのスレッドに対して pthread_join を実行するまで、そのメモリ リソース (スレッド記述子とスタック) は割り当て解除されません。そのため、メモリ リークを避けるために、作成された結合可能なスレッドごとに pthread_join を 1 回呼び出す必要があります。
つまり、スレッドの実行後に参加しないと、スレッドのリソースが解放されず、メモリ リークが発生します。
解決策は 2 つあります:
a. スレッドによって実行される関数内で
1 2 3 4 5 6 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー |
void* flush_thread_work(void* args) { //....do something pthread_detach(pthread_self()); return NULL; } ログイン後にコピー |
b. スレッドの開始時に、スレッドの PTHREAD_CREATE_DETACHED 属性を設定します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ログイン後にコピー |
pthread_attr_t attr; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); int ret=pthread_create(&thread_id, &attr, flush_thread_work, (void*)&m_sql_client); if(ret!=0){ //记住attr也要析构,否则又是一个内存泄漏 pthread_attr_destroy (&attr); APPSCORE_ERROR("Thread creation failed:%d",ret); return ret; } //记住attr也要析构,否则又是一个内存泄漏 pthread_attr_destroy (&attr); ログイン後にコピー |
このようにして問題は解決できます。
参照:
隠れたメモリ リークを解決しました - pthread_create 後にデタッチされないため、メモリが増加し続けます
2. php の json_encode 関数の問題
会社で PHP と C++ を使用してネットワークと対話するアプリケーションを作成したため、より一般的なシリアル化形式である json を選択しましたが、奇妙な問題が発生しました。
まず次のコード (php) を見てみましょう:
1 2 3 4 5 ログイン後にコピー ログイン後にコピー ログイン後にコピー |
$objs = array(); $objs[1] = 'a'; $objs[2] = 'b'; $objs[4] = 'd'; echo json_encode($objs)."\n"; ログイン後にコピー |
出力結果は以下のとおりです:
{"0":"a","1":"b","3":"d"}
これは正常であり、jsoncpp を使用して正しく解析できます。PHP は $objs を連想配列として自動的に扱い、json データを生成します。
ただし、コードを次のように変更すると、
1 2 3 4 5 6 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー |
$objs = array(); $objs[0] = 'a'; $objs[1] = 'b'; $objs[2] = 'c'; $objs[3] = 'd'; echo json_encode($objs)."\n"; ログイン後にコピー |
出力結果は次のようになります:
["a","b","c","d"]
jsoncpp は前の解析方法に従って解析できません~
実際、PHP の場合、これも合理的です。問題は、PHP では通常の配列と連想配列は両方とも配列ですが、C++ ではベクトルとマップがあるため、それでも json_encode で連想配列形式を生成したい場合は、次に、次のように記述する必要があります:
1 2 3 4 5 6 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー |
$objs = array(); $objs[0] = 'a'; $objs[1] = 'b'; $objs[2] = 'c'; $objs[3] = 'd'; echo json_encode((object)$objs)."\n"; ログイン後にコピー |
結果は次のとおりです。
{"0":"a","1":"b","2":"c","3":"d"}
3. このブログのフィードが遅れて更新されない理由
私は feedsky のフィード更新に非常に不満を持っていたので、オンラインの慣例に従い、feed.vimer.cn を確立しました。このブログが置かれているドメイン名スペースには、ドメイン名に基づいてサブディレクトリ (フィード) が自動的に作成され、.vimer.cn が変更されます。このディレクトリ内の htaccess ファイルは次のとおりです:
1 2 3 4 5 ログイン後にコピー ログイン後にコピー ログイン後にコピー |
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule . http://feed.feedsky.com/vimer [L] </IfModule> ログイン後にコピー |
その後、feed.vimer.cn にアクセスすると、自動的に http://feed.feedsky.com/vimer にジャンプします。
ただし、問題を見落としていました。つまり、WordPress のデフォルトのフィード リンクは http://vimer.cn/feed/rss2 であり、/feed/rss2 はサブディレクトリに解析され、自動的に http://feed にジャンプします。 feedsky .com/vimer なので、feedsky は http://feed.feedsky.com/vimer にリンクされているフィードを読み続けますが、もちろん新しいデータはありません。 。
結局、この方法は放棄されたようですが、feedsky は本当に不当な扱いを受けたようです~~~
。以上、最近のまとめでした~