ioctlによる方法だと特別な権限が必要になってしまう。特別な権限無しにbeep音をだしたかったので、PortAudioを使うことにした。
テスト用のファイルのうち"sin"とつくものを適当に改造すれば、任意の周波数のbeep音を出すことができる。
2009-11-18
様々な周波数のbeep音を出す。
ioctl(fd, KIOCSOUND, val);で、様々な周波数のbeep音を出すことができる。要root権限。
#define CLOCK_TICK_RATE 1193180
int main(int argc, char *argv[])
{
int fd;
int ret;
int freq;
int val;
fd = open("/dev/console", O_WRONLY);
if (fd == -1) {
perror("open");
exit(1);
if (argc > 1) {
freq = atoi(argv[1]);
val = (int)(CLOCK_TICK_RATE/freq);
} else {
val = 0;
}
ret = ioctl(fd, KIOCSOUND, val);
if (ret < 0) {
perror("ioctl");
exit(1);
}
return 0;
}
2009-08-13
ITRONのランデブ機能を使って、mallocで確保したメモリを受け渡してはいけない
ITRONには、ランデブという機能がある。
簡単に説明すると、タスクAからタスクBにメッセージを送り、BからAにその返答を返すことができる機能。
ぱっと見便利な機能なのだが、タスクAからタスクBにメッセージを渡すときに、malloc()等で動的に確保したメモリのポインタを渡すことができないというワナがある。
このワナを知らないと、メモリリークを起こす。
以下、詳細。
タスクAからメッセージを送るときには、cal_por()またはtcal_por()というAPIを使う。
これでタスクAは、タスクBにmsgを送ることができる。
タスクB側は、以下のようなコードになる。
タスクBがrpl_rdv()を呼ぶと、タスクAのtcal_por()がリターンして、タスクAはタスクBから返答を受け取ることができる。(返答は、tcal_por()の第3引数msgの指すアドレスに上書きされる)
ここで問題となるのは、tcal_por()がタイムアウトした場合。
tcal_por()は、タスクBから一定時間内にrpl_rdv()が呼ばれなかった場合にタイムアウトする。タスクBがacp_por()でメッセージを受け取ったかどうかは関係が無い。
すなわちタスクAは、タスクBがacp_por()でAからのメッセージを受け取ったかどうかを判断することができない。
以下のように、malloc()で動的に確保したメモリをメッセージに含めて、tcal_por()に渡したとする。
tcal_por()がタイムアウトした場合、free()は一体誰が呼べば良いだろうか?
メッセージはタスクBに伝わっていればBがfree()し、伝わっていなければAがfree()すべきである。
しかし、タスクAは、メッセージが伝わっているのか否かを判断することができないのである。
---
タイトルがちょっと不正確なので、正しく書き直すと、
「ITRON4準拠のランデブ機能を使うときに、mallocで確保したアドレスを含むメッセージをtcal_por()に渡してはいけない。」
簡単に説明すると、タスクAからタスクBにメッセージを送り、BからAにその返答を返すことができる機能。
ぱっと見便利な機能なのだが、タスクAからタスクBにメッセージを渡すときに、malloc()等で動的に確保したメモリのポインタを渡すことができないというワナがある。
このワナを知らないと、メモリリークを起こす。
以下、詳細。
タスクAからメッセージを送るときには、cal_por()またはtcal_por()というAPIを使う。
tcal_por(portid, 0x1, msg, msgsize, timeout);
これでタスクAは、タスクBにmsgを送ることができる。
タスクB側は、以下のようなコードになる。
acp_por(portid, 0x1, &retno, buf); /* tcal_porされるのを待つ */
...
rpl_rdv(retno, retmsg, sizeof(retmsg)); /* タスクAに返答を返す */
タスクBがrpl_rdv()を呼ぶと、タスクAのtcal_por()がリターンして、タスクAはタスクBから返答を受け取ることができる。(返答は、tcal_por()の第3引数msgの指すアドレスに上書きされる)
ここで問題となるのは、tcal_por()がタイムアウトした場合。
tcal_por()は、タスクBから一定時間内にrpl_rdv()が呼ばれなかった場合にタイムアウトする。タスクBがacp_por()でメッセージを受け取ったかどうかは関係が無い。
すなわちタスクAは、タスクBがacp_por()でAからのメッセージを受け取ったかどうかを判断することができない。
以下のように、malloc()で動的に確保したメモリをメッセージに含めて、tcal_por()に渡したとする。
msg.pointer = malloc(msgsize);
tcal_por(portid, 0x1, msg, msgsize, timeout);
tcal_por()がタイムアウトした場合、free()は一体誰が呼べば良いだろうか?
メッセージはタスクBに伝わっていればBがfree()し、伝わっていなければAがfree()すべきである。
しかし、タスクAは、メッセージが伝わっているのか否かを判断することができないのである。
---
タイトルがちょっと不正確なので、正しく書き直すと、
「ITRON4準拠のランデブ機能を使うときに、mallocで確保したアドレスを含むメッセージをtcal_por()に渡してはいけない。」
2009-08-07
ソフトウェアの設計とは、ドキュメントを書くことではない
ソフトウェアの設計の目的は、当たり前だが、よい設計をすることが目的である。
決して良いドキュメントを作ることではないし、良いドキュメントを作ることが目的となってはいけない。
良い設計をするためには、様々なドキュメントを作成する必要がある場合もある。
シーケンス図、ステートチャート、関数仕様書、などなど。
しかしこれらは、良い設計を行うために必要となった場合に作成するものだ。
「設計時には、○○図と○○図を作成すること」
などとルール化を行うのは、以下の理由から弊害がある。
また、設計が終わるまで一切コードを書いてはいけない、というのもよくある誤解である。
設計図を書くのも、(擬似)コードを書くのも、いわばシミュレーションを行っているようなものだ。それぞれのシミュレーション方法によって、検証できる範囲が異なる。
コードを書く方が容易に検証できる事を、無理に設計図で検証を行おうとするのは時間の無駄である。
---
注意:
ドキュメントによっては、設計内容を後で他人(数ヶ月後の自分を含む)に伝えるためにつくられるものもあるので、設計時に不要=作成不要、ではない。
ただその目的のドキュメントなら、実装の後に作成しても遅くはない。
どうせ、設計は変わる可能性があるのだから。
決して良いドキュメントを作ることではないし、良いドキュメントを作ることが目的となってはいけない。
良い設計をするためには、様々なドキュメントを作成する必要がある場合もある。
シーケンス図、ステートチャート、関数仕様書、などなど。
しかしこれらは、良い設計を行うために必要となった場合に作成するものだ。
「設計時には、○○図と○○図を作成すること」
などとルール化を行うのは、以下の理由から弊害がある。
- 不要なドキュメントまで作成してしまう可能性がある。
- ルールに明記したドキュメントを作ればOKという思考停止に陥り、本当に必要な設計が行われない可能性がある。
また、設計が終わるまで一切コードを書いてはいけない、というのもよくある誤解である。
設計図を書くのも、(擬似)コードを書くのも、いわばシミュレーションを行っているようなものだ。それぞれのシミュレーション方法によって、検証できる範囲が異なる。
コードを書く方が容易に検証できる事を、無理に設計図で検証を行おうとするのは時間の無駄である。
---
注意:
ドキュメントによっては、設計内容を後で他人(数ヶ月後の自分を含む)に伝えるためにつくられるものもあるので、設計時に不要=作成不要、ではない。
ただその目的のドキュメントなら、実装の後に作成しても遅くはない。
どうせ、設計は変わる可能性があるのだから。
2009-08-03
効果の薄い英語学習法
私の経験に基づいた、効果の薄い英語学習法。
人によっては当てはまらないものもあるだろうが、多くの人には当てはまると思う。
■発音の乗っていない辞書を使う。
単語のスペルや意味と発音は、同時に覚えなくては、使い物にならない。
後から発音を覚えるのは、二度手間になる。
■発音記号を覚えない。
caught, coat、など、発音の違いを知らないと、その単語を聴いたときに、文脈から意味を推測しなくてはならなく、リスニングが大変。
発音記号はできるだけ早いうちに覚え、単語は正しい発音で覚える必要がある。
■簡単な文法でも話せないのに、小洒落た表現を暗記する。
小洒落た表現は、暗記しても使うことが少ないので、すぐに忘れてしまう。
■英語のリスニングと称して、英語の音声をながら聞きする。
短い時間でも、集中して聴く方がリスニングの訓練になる。
流して長時間聞いていても、あまり訓練にならない。
■スクリプトや字幕がない英語を聴く。
何と言っているのか正解を確認する方法がないものをいくら聴いても、何も覚えられない。
■アメリカ英語、イギリス英語の発音を混ぜて学習する
発音方法を混ぜて学習すると、混乱するし正しい発音が分からなくなる。
どれか一つの発音を覚えると、自然と他の発音も分かるようになる。
■次々と新しい英語を聴く
同じものを何度も何度も繰り返し聴く方が覚えるのが早い。
ちなみに、私がリスニングの練習に使っているのは、これ。
Nonstop English Wave
月刊なのだが、1ヶ月では私にはペースが早いので、2ヶ月に1度ほどのペースで買っている。
追記: 上のリンクは、古かった。
新しいリンクはこちら
人によっては当てはまらないものもあるだろうが、多くの人には当てはまると思う。
■発音の乗っていない辞書を使う。
単語のスペルや意味と発音は、同時に覚えなくては、使い物にならない。
後から発音を覚えるのは、二度手間になる。
■発音記号を覚えない。
caught, coat、など、発音の違いを知らないと、その単語を聴いたときに、文脈から意味を推測しなくてはならなく、リスニングが大変。
発音記号はできるだけ早いうちに覚え、単語は正しい発音で覚える必要がある。
■簡単な文法でも話せないのに、小洒落た表現を暗記する。
小洒落た表現は、暗記しても使うことが少ないので、すぐに忘れてしまう。
■英語のリスニングと称して、英語の音声をながら聞きする。
短い時間でも、集中して聴く方がリスニングの訓練になる。
流して長時間聞いていても、あまり訓練にならない。
■スクリプトや字幕がない英語を聴く。
何と言っているのか正解を確認する方法がないものをいくら聴いても、何も覚えられない。
■アメリカ英語、イギリス英語の発音を混ぜて学習する
発音方法を混ぜて学習すると、混乱するし正しい発音が分からなくなる。
どれか一つの発音を覚えると、自然と他の発音も分かるようになる。
■次々と新しい英語を聴く
同じものを何度も何度も繰り返し聴く方が覚えるのが早い。
ちなみに、私がリスニングの練習に使っているのは、これ。
Nonstop English Wave
月刊なのだが、1ヶ月では私にはペースが早いので、2ヶ月に1度ほどのペースで買っている。
追記: 上のリンクは、古かった。
新しいリンクはこちら
2009-07-06
Java言語で学ぶデザインパターン入門 マルチスレッド編
2009-06-18
プログラムのスキルのうち、最も修得が難しいスキルは何か
プログラマに必要なスキルは数多くあると思うが、一番修得しにくいスキルはダントツで、
「並列動作するシステムを、レースコンディションやデッドロックが無いように正しく作る」
ではないかと思う。
並列動作のためのデザインパターン本があればいいのに。
あまり売れるとは思えないけど、私は欲しい。
「並列動作するシステムを、レースコンディションやデッドロックが無いように正しく作る」
ではないかと思う。
並列動作のためのデザインパターン本があればいいのに。
あまり売れるとは思えないけど、私は欲しい。
2009-05-22
テストリストファースト開発
テストファーストという開発手法があるが、この手法は前程として
・テストリストの作成
・テストの実装
の2つの物を、分けられない物としているのではないだろうか。
(多分そうなのだと思うけど、アジャイル開発手法にあまり詳しくないので、違うかも)
私の経験上では、たいていの場合は
1. テストリストを作成する
2. 実装する。
3. テストを実装する。
という順で開発を行うのが、一番効率が良い。
つまり、テストファーストではなく、テストリストファースト。
テストを先に実装してしまうと、実装方法や計設が変わってテストを作り直しになってしまう場合に、ロスが大きい。
・テストリストの作成
・テストの実装
の2つの物を、分けられない物としているのではないだろうか。
(多分そうなのだと思うけど、アジャイル開発手法にあまり詳しくないので、違うかも)
私の経験上では、たいていの場合は
1. テストリストを作成する
2. 実装する。
3. テストを実装する。
という順で開発を行うのが、一番効率が良い。
つまり、テストファーストではなく、テストリストファースト。
テストを先に実装してしまうと、実装方法や計設が変わってテストを作り直しになってしまう場合に、ロスが大きい。
登録:
投稿 (Atom)
