メモリ不足-Chromium on LinuxでTab discardingが使用できるように
Linuxでchromiumによるメモリ不足に悩まされてきましたが
chromium 57からchrome:discardsが使用できるようになります。
このコミットで有効化されたようです
d2ee5e6f646b503fcb77a0597d8d38774e36aaa8 - chromium/src.git - Git at Google
これでOOM頻発から解放されます。
まだstableになっていないようですが、
Download Chromium
ここから最新ビルドをダウンロードすれば一足先に利用できます。
ChromeのDev channelとかでも大丈夫でしょう
Xen導入からライブマイグレーションまで Ubuntu16.04LTSをdom0に
IGGG Advent Calendar 2016 19日目の記事です。
余計なまえがきは最後尾に移されました
昨日はnatuRulOさんのバイオインフォマティクスの話でしたこういう話はなんか読んでるだけでわくわくします。
本題
最近巷でライブマイグレーションが人気らしいので
今回はUbuntuをdom0としたXenの環境構築を大きく5ステップくらいで。(dom0:仮想化環境管理に使うOS環境)
Read moreDiffie-Hellman Kx demo
Diffie-Hellman 鍵交換について
ご存知な方は多いとは思いますが
簡単に言えばAさんとBさんが内緒の会話をしたい時に
Eさんが近くで聞き耳をたてていても暗号(鍵)の共有ができる
つまり(Diffie-Helllman Kx + 暗号)を使えば初対面、公衆の面前で内緒話ができます。
前提条件
- みんな鍵交換の方法、generator,primeの値は知っている。
- AさんはBさんを他の人と識別可能&逆も
正しいのかどうかわからない説明はこれくらいにして
デモ
数値 | generator: | 素数 prime: |
---|---|---|
人 | Alice | Bob |
任意の秘密な数 | ||
g^a,g^b | Not calculated yet | Not calculated yet |
A=(g^a)mod p,B=(g^b)mod p | Not calculated yet | Not calculated yet |
交換 | Not calculated yet | Not calculated yet |
(B^a),(A^b) | Not calculated yet | Not calculated yet |
Ka=(B^a)mod p,Kb=(A^b)mod p | Not calculated yet | Not calculated yet |
Ka==Kbとなれば共有できたということになます。
説明などあいまいなので指摘大歓迎です
おしまい
数値 | generator: | prime: |
---|---|---|
任意の秘密な数 | ||
g^a | Not calculated yet | |
A=(g^a)mod p | Not calculated yet | |
交換 | ||
(B^a) | Not calculated yet | |
K=(B^a)mod p | Not calculated yet |
テスト用シーザー暗号
Key:
送信メッセージ(ひらがな)
暗号文:
受信メッセージ:---Interruptible SleepをC++のmutexで
IGGG Advent Calendar 2016 13日目の記事です
蛇足的イントロ
Expandさて
昨日のsakuragiさんの記事と比べるとかなり有用性は低いです
別スレッドから中断可能な最大時間指定スリープを作りたい。
C++11使用。
Thread間の調停なので
まずはmutexについて。
mutex(mutual exclusion)について
排他制御を行なう機構です。
電車の閉塞を例にとって説明してみます。
ある区間に複数の電車が入っていると正面衝突、追突など事故の原因になります。
そこで電車はある区間に1編成のみしか入れないようにしています。
閉塞システムの一つであるタブレット閉塞でmutexを説明します。
この方式では「タブレット」を持っている電車のみ線路に進入できます。 タブレットは機械を操作して取り出せます。ひとつ取り出すと戻すまで新しいタブレットは取り出せません。詳しくはタブレット閉塞で検索してみてください
mutexと比較して考えてみると、閉塞機を操作してタブレットを取り出すことがlock(mutex)に、unlockがタブレットを戻す操作になります。unlockし忘れることはタブレットを持ったまま運転士が逃走することと等価でしょう。
電車の話はここで終わりにして
mutexをスレッドで使用したときの流れ
Thread A | Thread B |
---|---|
std::mutex myheart | |
Lock(myheart) | ↓ |
*リソースを使用する処理 owns mutex | ↓ |
*リソースを使用する処理 owns mutex | Lock(myheart) blocked |
*リソースを使用する処理 owns mutex | -blocked |
Unlock(myheart) | -blocked |
↓ | *リソースを使用する処理 owns mutex |
↓ | Unlock(myheart) |
こんなふうにリソースの排他制御ができます。スコープを抜けたら自動でアンロックするためにstd::unique_lockやstd::lock_guardを使います。
std::condition_variable
条件が満たされるまで待ったりするためのクラス。
wait_for、wait_untilなんてメソッドがあります。
これを使って中断可能スリープを実現します。
condition_variableを利用したコード
class Test {
public:
std::mutex mutex_;
std::thread thread_;
std::condition_variable cond_;
ElapsedTimeMeasure<std::chrono::steady_clock> measure;
void worker(int wait_sec){
std::cout<<"Thread start"<<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
measure.start();
std::unique_lock<std::mutex> lock(mutex_);
std::cv_status result = cond_.wait_for(lock,std::chrono::seconds(wait_sec));
measure.stop();
if (result == std::cv_status::timeout) {
std::cout << "Timedout " ;
}else{
std::cout << "Interrupped " ;
}
std::cout<<"Slept for:"<<measure.get_seconds<double>()<<std::endl;
}
void notify(){
cond_.notify_all();
}
Test(int waitsec):thread_(&Test::worker,this,waitsec){ }
~Test(){
thread_.join();
std::cout<<"Destructor"<<std::endl;
}
};
int main(){
{
Test t(3);
std::this_thread::sleep_for(std::chrono::milliseconds(200));
//Call notify before calling wait_for in worker -> No effect
t.notify();
std::this_thread::sleep_for(std::chrono::milliseconds(500-200));
//The thread may be waiting
std::this_thread::sleep_for(std::chrono::seconds(1));
t.notify();
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
{
Test t(2);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
//The thread may be waiting
//wait_for may be timed out
std::this_thread::sleep_for(std::chrono::seconds(3));
t.notify();
}
return 0;
}
Expand
Thread start Interrupped Slept for:1.00007 Destructor Thread start Timedout Slept for:2.00009 Destructor
いいかんじに動きました
ちょっといじわる
int main(){
Test t(10);
return 0;
}
時計をステップで戻してみると
PC1
ExpandPC1 $ ./a.out&sleep 1&&sudo date --set="30 seconds ago" [1] 7560 Thread start Timedout Slept for:40.0009 Destructor [1] + 7560 done ./a.out PC1 $ ldd ./a.out linux-gate.so.1 => (0xb7772000) libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb7649000) libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb7603000) libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb75e4000) libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb75c8000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb741a000) /lib/ld-linux.so.2 (0xb7773000) PC1 $ ls -l /usr/lib/i386-linux-gnu/libstdc++.so.6 /usr/lib/i386-linux-gnu/libstdc++.so.6 -> libstdc++.so.6.0.21
失敗:10秒スリープ指示に対して40秒待っている
PC2
ExpandPC2 $ ./a.out &sleep 1&&sudo date --set="30 seconds ago" [2] 19928 Thread start Timedout Slept for:10.0074 Destructor [2]- Done /dev/shm/a.out PC2 $ ldd ./a.out linux-vdso.so.1 => (0x00007ffe139c1000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd3e0704000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd3e04ee000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd3e02d0000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd3dff07000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd3dfbfe000) /lib64/ld-linux-x86-64.so.2 (0x000055fd00479000) PC2 $ ls -l /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/lib/x86_64-linux-gnu/libstdc++.so.6 -> libstdc++.so.6.0.21
成功
PC1では失敗PC2では成功
難解スパイラル
こうなったらpthreadを直接触って問題回避
Expandclass InterruptibleSleep{
pthread_condattr_t attr;
pthread_mutex_t mutex;
pthread_cond_t cond;
public:
public:
enum SleepResult {
TIMEDOUT,INTERRUPTED
}; InterruptibleSleep(){
pthread_condattr_init(&attr);
if(int err=pthread_condattr_setclock(&attr,CLOCK_MONOTONIC)){
std::cerr<<"Failed to set clock."<<err<<std::endl;
}
mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_init(&cond,&attr);
}
~InterruptibleSleep(){
pthread_cond_destroy(&cond);
pthread_condattr_destroy(&attr);
}
template<class Rep,class period>
SleepResult sleep(std::chrono::duration<Rep,Period> rel_time){
pthread_mutex_lock(&mutex);
SleepResult result=INTERRUPTED;
struct timespec timeout;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC,&now);
int sleep_reltime=(std::chrono::duration_cast<std::chrono::duration<int,std::ratio<1,1>>> (rel_time)).count();
timeout.tv_sec=now.tv_sec+ sleep_reltime;
timeout.tv_nsec=now.tv_nsec;
int rc=pthread_cond_timedwait(&cond,&mutex,&timeout);
if(rc==ETIMEDOUT){
result=TIMEDOUT;
}else{
result=INTERRUPTED;
}
pthread_mutex_unlock(&mutex);
return result;
}
void notify(){
pthread_cond_broadcast(&cond);
}
};
int main(){
{
ElapsedTimeMeasure<std::chrono::steady_clock> measure;
InterruptibleSleep t;
std::thread thread([&]{
measure.start();
InterruptibleSleep::SleepResult result=t.sleep(std::chrono::seconds(10));
measure.stop();
if(result==InterruptibleSleep::SleepResult::TIMEDOUT){
std::cout<<"Timedout ";
}else{
std::cout<<"Interrupted ";
}
std::cout<<"Slept for:"<<measure.get_seconds<double>()<<std::endl;
});
thread.join();
}
return 0;
}
Expand
PC1 $ ./a.out&sleep 1&&sudo date --set="30 seconds ago" [1] 25678 Timedout Slept for:10.0408 [1] + 25678 done ./a.out
CLOCK_MONOTONICがミソ。
C++関係なくなった
おまけ
昨日の記事についてのリアクションをどこに書けばいいのか分からないのでここに
[sudo] apt install openconnect [sudo] openconnect --juniper <SERVER>
これでも行けるかもしれません(未検証)。 1日目の方法と同じくtun関係で詰まったりするのかな?
on Windowsではビルドが必要かも
嘘だったらごめんなさい
追記:sakuragiさんが検証してくださいました。できたそうです。sakuragiさんありがとうございます。詳しくはコメント欄を参照ください。
Omake2
明日はnoobさんです。Marp初耳ですが個人的に楽しみにしています。