Home > Unix Archive
Unix Archive
n日前より古いファイルを消す
- 2009-05-12 (Tue)
- Unix

バックアップスクリプトを書く時にいつも忘れるのでメモ。
DATE=`date -d '7 days ago' +%y%m%d0000` echo $DATE echo >temp.file touch -t $DATE temp.file find . ! -newer temp.file -print | xargs rm -f rm temp.file
findコマンドの-newerを使用しています (お好みで-anewer, -cnewerなど)。
P.S.
chunさんよりzshのextended_globを覚えろとの指令が飛びました。
setopt extended_glob; ls *(^m-7) -ld
おー。
P.S.2
Higeponさんから以下のようなfindの使い方を教えて頂きました。find高機能すぎ。
find /tmp/ -name "sess_*" -mtime +7 -delete
- Comments: 0
- Trackbacks: 0
epoll(2)とselect(2)の計算量
- 2007-11-20 (Tue)
- Unix

研究室でid:yama6がepollとか言っていて、mixi Engineers’ Blog さんの「Linux Programming、epollの話」を思い出した。
パフォーマンスの方はselect(2)とpoll(2)のtime complexityがO(n)に対しepollはO(1)と無視のできない性能の差を実現しています。
これこれ、書こうとして忘れてた。僕の理解だとepoll(2)はO(n)でselect(2)がO(n^2)です。この差はsignificantですよ!
例えば1万個のソケットを管理しているとします。で、ソケットが1個づつ順番に読み込み可能になるという最悪のシチュエーションを考えて見ます。select(2)だと10000 * 10000のループが回ります。epoll(2)だと10000 * 1回のループが回ります。
そういう上手いペースで接続をする方法を思いつかないので、実データで示せないのが申し訳ないですが。libeventのグラフもO(n ^ 2)の曲線になってませんな…。
- Comments: 2
- Trackbacks: 0
close(2) while select(2)ing
- 2007-11-16 (Fri)
- Unix

昨日ちゅんさんと話していた話題。select(2)中に監視対象のディスクリプタを別スレッドからclose(2)したらどうなるの?epoll(2)だと?
以下のような事を試してみた。
[code]
thread1 thread2
——————————–
(r,w) <-pipe()
select(fdset = {r})
close(r)
close(w)
(r2, w2) <- pipe() // 同じfdになる
write(w2)
[/code]
select(2)版コード
[code]
void* fd_consumer(void *writefd_){
int* pipefd = (int*)writefd_;
sleep(1);
close(pipefd[0]);
close(pipefd[1]);
cerr << "close(2) pipe" << endl;
sleep(1);
if(pipe(pipefd)){ perror("Failed to make pipe"); exit(1); }
cerr << "pipe(2) in another thread: " << pipefd[0] << ", " << pipefd[1] << endl;
sleep(1);
cerr << "write(2) to pipe" << endl;
char buf[] = "a";
write(pipefd[1], buf, 1);
return NULL;
}
int main(void){
int pipefd[2];
if(pipe(pipefd)){
perror("failed to make pipe");
exit(1);
}
cerr << "pipe(2): " << pipefd[0] << ", " << pipefd[1] << endl;
fd_set rfds;
fd_set wfds;
fd_set efds;
pthread_t thread;
pthread_create(&thread, NULL, fd_consumer, (void *)pipefd);
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
FD_SET(pipefd[0], &rfds);
FD_SET(pipefd[0], &wfds);
FD_SET(pipefd[0], &efds);
struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0;
int r = select(pipefd[0]+1, &rfds, &wfds, &efds, &tv);
if(r < 0){
cerr << "select(2) error" << endl;
} else if (r == 0){
cerr << "select(2) timedout" << endl;
}else{
cerr << "select(2) catched " << r << " elements" << endl;
}
if(FD_ISSET(pipefd[0], &rfds))
cerr << "pipefd[0] set(rfds)" << endl;
if(FD_ISSET(pipefd[0], &wfds))
cerr << "pipefd[0] set(wfds)" << endl;
if(FD_ISSET(pipefd[0], &efds))
cerr << "pipefd[0] set(efds)" << endl;
return 0;
}
[/code]
epoll(2)版コード
[code]
void* fd_consumer(void *writefd_){
int* pipefd = (int*)writefd_;
sleep(1);
close(pipefd[0]);
close(pipefd[1]);
cerr << "close(2) pipe" << endl;
sleep(1);
if(pipe(pipefd)){ perror("Failed to make pipe"); exit(1); }
cerr << "pipe(2) in another thread: " << pipefd[0] << ", " << pipefd[1] << endl;
sleep(1);
cerr << "write(2) to pipe" << endl;
char buf[] = "a";
write(pipefd[1], buf, 1);
return NULL;
}
int main(void){
int epfd = epoll_create(10);
int pipefd[2];
if(pipe(pipefd)){
perror("failed to make pipe");
exit(1);
}
cerr << "pipe(2): " << pipefd[0] << ", " << pipefd[1] << endl;
struct epoll_event epev;
memset(&epev, 0, sizeof(epev));
epev.events = EPOLLIN;
epev.data.fd = pipefd[0];
epoll_ctl(epfd, EPOLL_CTL_ADD, pipefd[0], &epev);
pthread_t thread;
pthread_create(&thread, NULL, fd_consumer, (void *)pipefd);
struct epoll_event events[10];
int r = epoll_wait(epfd, events, 10, 5000);
if(r < 0){
cerr << "epoll(2) error" << endl;
} else if (r == 0){
cerr << "epoll(2) timedout" << endl;
}else{
cerr << "epoll(2) catched " << r << " elements" << endl;
}
for(int i=0; i
cerr << "EPOLLIN" << endl;
if(events[i].events & EPOLLOUT)
cerr << "EPOLLOUT" << endl;
if(events[i].events & EPOLLERR)
cerr << "EPOLLERR" << endl;
if(events[i].events & EPOLLHUP)
cerr << "EPOLLHUP" << endl;
}
return 0;
}
[/code]
実行結果
[code]
mac% g++ seltest.cpp -Wall; time ./a.out
pipe(2): 3, 4
select(2) error
pipefd[0] set(rfds)
pipefd[0] set(wfds)
pipefd[0] set(efds)
./a.out 0.00s user 0.01s system 0% cpu 1.011 total
[/code]
[code]
linux% g++ -Wall seltest.cpp -lpthread; time ./a.out
pipe(2): 3, 4
close(2) pipe
pipe(2) in another thread: 3, 4
write(2) to pipe
select(2) catched 1 elements
pipefd[0] set(rfds)
./a.out 0.00s user 0.00s system 0% cpu 5.007 total
[/code]
[code]
linux% g++ -Wall epolltest.cpp -lpthread; time ./a.out
pipe(2): 4, 5
close(2) pipe
pipe(2) in another thread: 4, 5
write(2) to pipe
epoll(2) timedout
./a.out 0.00s user 0.00s system 0% cpu 5.007 total
[/code]
結果
select(2)だとMacOS XとLinuxで挙動が違う。未定義動作?
Macの方の動作を意図してselect(2)を使ったプログラムを書いていたので、ちょっと困った。代替となるportableな方法無いかなぁ。
- Comments: 3
- Trackbacks: 0
libaio(Linuxの非同期I/Oライブラリ)の使い方
- 2007-06-05 (Tue)
- Unix

Linuxで非同期I/Oを行うためのライブラリ「libaio」の使い方を書いてみる事にする。少し昔の話になるが、lighttpdが使用し、スループットを80%も上げたらしい。
TOEFLに向けて転置ファイルについての論文(Inverted files for text search engine [moffat 06])でReading対策をしていたところ、意外とスニペット(検索にヒットした箇所の前後の文章)を作るところが時間がかかるという事を教えてもらったので、適当にそれを例題にしてみる。具体的には以下のようなコードを非同期I/Oを使用して速くなるかどうか見てみる。
for (unsigned int i = 0; i < files.size(); i++) {
FILE* fp = fopen(files[i].c_str(), "rb");
if (fp == NULL) continue;
fseek(fp, offsets[i], SEEK_SET);
char buf[64];
size_t nread = fread(buf, 1, 64, fp);
fclose(fp);
}
ファイルリストとそれに付随するオフセットのリストが与えられた時、各ファイルの指定位置から64 byteづつ読み込むようなプログラムだ。
色々高速化する手段は有るが、日本語でlibaioの使い方が解説してあるところがなかったので、布教も兼ねて書いてみる。
- Comments: 4
- Trackbacks: 0
flock(2)はスレッドも排他するか?(2)
- 2007-05-27 (Sun)
- Unix

flock(2)ではなくlockf(3)だとメールを頂いた。
確かにlockf(3)に変えてみると(lenは0)、排他してくれない。なんで挙動が違うんだ・・・。
2つの違いが分かったらまた書きます。
- Comments: 1
- Trackbacks: 0
Home > Unix Archive
-
- February 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
