ラベル 微妙な実験シリーズ の投稿を表示しています。 すべての投稿を表示
ラベル 微妙な実験シリーズ の投稿を表示しています。 すべての投稿を表示

2010年9月8日水曜日

みくった〜♪のWindows版をMinGWでビルドしてみた

みくった〜♪は、全てのミク廃、そしてTwitter中毒者へ贈る、至高のTwitter Clientを目指すTwitter Client…として@toshi_a氏が開発しているソフトウェアである。

みくった〜♪

主にLinux向けとして開発されているようだが、初公開の時点で「Windows版無いの(´・ω・`)?」と言われたように、Windows版の需要がやはりそれなりに存在する。
そこで、MinGW使ってRuby/GTK2環境を整え、Windowsでもみくった〜♪を動作させることはできないものか?と考え、実際にやってみた。

※ただ使ってみたいだけ、という方はみくった〜♪ for Windowsのページみくった〜♪ for Windows 毎日0,12時に自動ビルドされるバージョンからどうぞ。



ビルドに必要なソフトウェアやライブラリは以下の通り。
MinGW GCC 4.5.0
ftp://ftp.jaist.ac.jp/pub/sourceforge/m/project/mi/mingw/Automated%20MinGW%20Installer/mingw-get-inst/mingw-get-inst-20100831/mingw-get-inst-20100831.exe

ruby 1.8.7-p302
ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.7-p302.tar.bz2

ruby-gtk2-0.19.4
http://ftp.jaist.ac.jp/pub/sourceforge/r/project/ru/ruby-gnome2/ruby-gnome2/ruby-gnome2-0.19.4/ruby-gtk2-0.19.4.tar.gz

ruby-hmac-0.3
http://deisui.org/~ueno/ruby/hmac.html
http://deisui.org/~ueno/ruby/ruby-hmac-0.3.tar.gz

iconv
ftp://ftp.gnu.org/gnu/libiconv/libiconv-1.13.1.tar.gz

GTK+
http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.20/gtk+-bundle_2.20.0-20100406_win32.zip

Win32 OpenSSL
http://www.slproweb.com/products/Win32OpenSSL.html
http://www.slproweb.com/download/Win32OpenSSL-0_9_8o.exe

Microsoft Visual C++ 2008 SP1 再頒布可能パッケージ (x86) OpenSSL用
http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=ja

可能な限りソースからビルドするようにしたが、OpenSSLとGTK+は面倒だったので、とりあえずWindows用バイナリを利用することにした。…OpenSSLをMinGWでビルドすれば、MSVC++ランタイム要らなくなるのだが…。



MinGWによるビルド環境の構築


以前はMinGW(コンパイラ)とMSYS(サブシステム)を個別に用意し、セットアップする必要があったが、現在はmingw-get-instパッケージに纏められた模様。これをダウンロードし、普通のソフトウェアのインストーラと同じようにウィザードを進めていくだけでビルド環境が整う。
デフォルトでは、Windowsのパス変数もMSYSのパス変数として登録されてしまい、混乱の原因となるので、PATH変数を変更しておく。

$ PATH="/mingw/bin:/usr/local/bin:/bin"




iconvのビルド


一番最初にiconvをビルドする。といっても、普通に

$ ./configure --prefix=/mingw
$ make
$ make install

のような感じでおk。
本当なら/usr/localあたりにprefixを置いて、そこにインストールすべきな筈なのだが、私のCFLAGSやLDFLAGSの認識がおかしいのか、rubyのiconvライブラリのextconf.rbが/usr/localに置いたiconvを見つけられないため、諦めて/mingwにprefixを置く。



必要なライブラリの展開


GTK+のアーカイブを解凍し、そのまま全て/mingwに展開する。
OpenSSLは、インストーラを実行しインストールした先にあるディレクトリを、GTK+同様に/mingwに展開する。
また、OpenSSLを利用するために必要なMicrosoft Visual C++ 2008 SP1 再頒布可能パッケージ (x86)もインストールしておく。



Rubyのビルド


いつも通りRubyをビルドする。

$ ./configure --prefix=/ruby
$ make
$ make install

prefixを/rubyにしたが、make installする際にMSYSの/を飛び越えるため(コンパイルしたRubyがインストールに使用されるから?)、Windows側の\rubyにインストールされるので注意が必要。
そして、Windows側にインストールされたRubyを、MinGWの/usr/localあたりに移動しておく。



Ruby/GTK2のビルド


Ruby/GTK2のアーカイブを解凍し、extconf.rbを先程作成したRubyで実行する。

$ /usr/local/bin/ruby extconf.rb

そして後はmake、make installするだけの筈なのだが、MinGWでRuby/GTK2をビルドすると何故か毎度gtkのビルドでコケる。
どうやらこれからビルドされる筈のgtk2.soを、ビルド前にリンクしようとするかららしい。
そこで、gtkのMakefileを編集する。
何らかのエディタでgtk/src/Makefileを開き、LIBS = $(LIBRUBYARG_SHARED)...で始まる行の、-lgtk2を削除。

後はいつも通り。

$ make
$ make install


この時点で、Ruby/GTK2自体の開発/実行環境は整っていることになる。
MSYSでの作業はここで終了。



必要なファイルのみを纏め、最小限のRuby/GTK実行環境を作成


MSYSの/usr/localにはRuby/GTKの実行環境が整っている(ライブラリは足りないが)ので、これを適当なディレクトリにコピーし、rubyディレクトリとする。
rubyディレクトリのbinに、iconv、OpenSSL、GTK+の*.dllをコピー。
そして、RubyのLOAD_PATHのどこかにruby-hmacを展開。
後はみくった〜♪をダウンロードして展開、普通に起動できれば、みくった〜♪実行環境完成となる。



mikutter.exeを作成


毎度コマンドラインでruby mikutter.rbとしたり、バッチファイルを実行するのはどことなく落ち着かない。
また、Rubyの環境すべてがrubyディレクトリに入っているので、配布するにしてもかなりのサイズになってしまう。
そこで、更に必要なファイルだけを纏め、Windowsの実行ファイル形式で配布する形をとる。
exeファイル化には、exerbを利用する。
exerbの使用方法は、
・mkexy mikutter.rbでレシピファイルmikutter.exyを自動生成
・exerb mikutter.exyとすると、mikutter.exeが作成される
という感じである。
ここで作成されたバイナリは、Ruby環境無しで動作するものなので、あとはmikutterのディレクトリ階層とdllの配置をするだけ。

exerbの詳しい使用方法、レシピファイルの書式については、
公式ページ http://exerb.sourceforge.jp/
やmikutter for Windows付属のmikutter.exyを参照して欲しい。



みくった〜♪ 本家
http://toshia.dip.jp/
http://mikutter.d.hachune.net/

みくった〜♪ for Windowsのページ
http://append.hachune.net/mikutter.html

みくった〜♪ for Windows 毎日0,12時に自動ビルドされるバージョン
http://file.hachune.net/mikutter/

2010年8月31日火曜日

今日ははつねさんの誕生日!

ということで、hachune.netとしてもなにかやらないといけないな、と。

それで完成したのがはちゅねドメインサービス!

簡単に言えば、Dynamic DNSとURL転送を切り替えながら使えるホスト名提供サービス、…ってところだろうか。
negi.d.hachune.netみたいなドメイン名を使ってボカロなサイト運営してみたい!って方が居ましたら、どんどん使ってあげてね!


はちゅねドメインサービス
http://www.hachune.net/domain.html


もっと分かりやすく面白い名前、募集中w

2010年7月7日水曜日

Debian LennyなMac MiniをPulseAudioサーバにする

Software Design 6月号やUbuntu Weekly Recipe 第106回 PulseAudioでリモートスピーカを使うで、Ubuntuでのスピーカーサーバの作り方が解説されていた。
UbuntuでできることがDebianでできない筈がねぇ!…ということで、Debianで挑戦してみた。

サーバ側


・alsa関連を入れる
# aptitude install alsa-utils


・PulseAudioとZeroConfモジュールを入れる
かなりパッケージ数が多いので注意。
# aptitude install pulseaudio pulseaudio-module-zeroconf


・サーバ起動時にPulseAudioデーモンが実行されるように設定する
/etc/default/pulseaudioのPULSEAUDIO_SYSTEM_START=0を1に変更。


・/etc/pulse/default.paを変更する

#load-module module-native-protocol-tcp
#load-module module-zeroconf-publish

以上の部分を、以下のように変更する。
auth-ip-acl=10.39.39.0/24は、サーバへのアクセスを許可するサブネットを指定する。

load-module module-native-protocol-tcp auth-ip-acl=10.39.39.0/24
load-module module-zeroconf-publish



・PulseAudioデーモンを起動する
# /etc/init.d/pulseaudio start


クライアント側


・paprefsをインストール
# aptitude install paprefs


・paprefsを起動し、Make disconverable PulseAudio network sound devices available locallyのチェックをOnにする


・「サウンドの設定」を開き、「出力」をpulse@サーバホスト名に設定する



後は、MPlayerやら何やらで再生して、サーバ側から音が出れば成功。
なかなか認識してくれない場合は、サーバをrebootしてみるのも手かもしれない。

2010年6月30日水曜日

RubyのYAMLライブラリで2バイト文字をそのまま扱う

RubyのYAMLライブラリでは、標準では日本語などの2バイト文字列をバイナリとして扱うようになっている。しかし、これでは人間が直接修正するのが非常に面倒である。

技術評論社のYAML解説ページには、Rubyのソースにパッチを当てビルドする方法や、ya2yamlを使用する方法が書いてあった。しかし、パッチを当てた環境をすべてに適用するのは非常に面倒であり、ya2yamlについては標準ライブラリではない上に、少々遅いという問題がある。

そこで、どうにかする方法はないものかとYAMLのソースを眺めていたところ、以下の方法であっさり解決してしまった。



#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-

require "yaml"
require "yaml/encoding"

# String.is_binary_data?で必ずfalseを返すように書き換える
class String
def is_binary_data?
return false
end
end

data = {"はつね"=>"みく", "はちゅね"=>"みく", "かがみね"=>"りん・れん", "めぐりね"=>"るか"}

# 通常どおり表示
puts "Escape:"
puts yaml = YAML.dump(data)

# アンエスケープして表示
puts "Unescape:"
puts yaml = YAML.unescape(yaml)


一度エスケープされたものをまた戻すという、面倒なことになっているが、ソース修正するよりマシかな…と。
これで、YAMLで書き出して手動で編集…なんてことがやりやすくなるかもしれない。

2010年4月10日土曜日

はちゅねCNAMEサービスも開始!

hachune.netドメイン有効活用計画第二弾、CNAME割り当てサービスを開始!

d.hachune.netのサブドメイン(例: mikutter.d.hachune.net)を、既に持っているドメイン名の別名として使用できるようにするサービスです。

これは、固定IPを持っているか、既にDynamicDNSなどでドメインを持っている向け、となります。

以下の場合は、利用出来ない場合があります。
・非固定IPアドレスで、Dynamic DNSでIPアドレスと関連付けられたドメインを持っていない
・ドメインを持っているが、IPアドレスを貰えないタイプのホスティングサービスを利用している(ブログサービスなど)


詳細ははちゅねCNAMEサービスのページでどうぞ。



対象者がかなり絞られる気もするけど…まぁ無いより良いよね(´・ω・`)
回線が光だったら、Dynamic DNSサービスとかホスティングサービスもできるんだが…

2010年3月22日月曜日

RubyでUDPなServer/Clientを作ってみた

なにやらUDPを使ったアプリケーションを作成することになりそうなので、各クライアントから来た要求を全クライアントに返すサーバと、送信/受信を行うクライアントを作成してみた。

UDPなので、相手に届いているかを保証することはできない。
よって、このサーバ/クライアントでは「伝えること」より「リアルタイムで発信すること」を重視する。


まずはサーバ側を作成。

#!/usr/bin/env ruby
#-*- encoding: utf-8 -*-

require "socket"

SERVERIP = "192.168.0.105"
SERVERPORT = "62000"

clientList = Array.new

sock = UDPSocket.new
# サーバとして待ち受けるアドレスとポートを指定 
sock.bind(SERVERIP, SERVERPORT)

while true
# sockに出力が来るのを待つ
# 来なかったらnilを返す
sel = IO::select([sock])
if sel != nil
sel[0].each {|s|
# 最大65535byte分のデータを受け取る。
# データは配列として渡される。
# ["文字列", ["アドレス種別", 送信元ポート番号, "送信元ホスト名", "送信元IPアドレス"]]
# ["192.168.0.105 :43433 miku > miku\n", ["AF_INET", 62000, "192.168.0.105", "192.168.0.105"]]
data = s.recvfrom_nonblock(65535)
string = data[0].chomp!
ip, port = data[1][3].to_s, data[1][1].to_i
clientList << {"ip"=>ip, "port"=> port}
clientList.uniq!
# 各クライアントに向けて返信する
clientList.each{|client|
printf("Server > %-15s:%5d %s\n", client["ip"], client["port"], string)
# 実際に返信する。send("文字列", フラグ, "送信先IPアドレス", "送信先ポート")
sock.send(sprintf("%-15s:%5d %s\n", client["ip"], client["port"], string), 0, client["ip"], client["port"])
}
}
end
end

sock.close


次にクライアント側を作成する。

#!/usr/bin/env ruby
#-*- encoding: utf-8 -*-

require "socket"

if ARGV[0] == nil
puts "ex) ./client.rb miku"
exit 1
end

NAME = ARGV[0]
SERVERIP = "192.168.0.105"
SERVERPORT = "62000"

# UDPのソケットを作成
sock = UDPSocket.new
# バインドするIPアドレスとポートを自動で割り当てる
sock.bind("0.0.0.0", 0)


# サーバからの情報を受け取り表示するスレッドを作成
thread = Thread.new {
while true
# sockに出力が来るのを5秒待つ。
# 来なかったらnilを返す。
sel = IO::select([sock], nil, nil, 5)
if sel != nil
sel[0].each{|s|
data = s.recvfrom_nonblock(65535)
puts data[0].chomp!
}
end
end
}

# サーバに情報を送信するループ
while true
string = STDIN.gets.chomp!
sock.send(sprintf("%-5s> %s\n", NAME, string), 0, SERVERIP, SERVERPORT)
end

sock.close



実際に使用すると、このようになった。
UDPサーバ/クライアント実行結果


これだけで、簡単なチャットサーバ/クライアントが作成できた。
Cで書いたものを見たあとだと、Rubyが簡単過ぎて泣ける。

2010年3月8日月曜日

Debian(PPC)でLinux-VServerを使ってみる

Debianでのchroot環境について調べていたところ、chrootよりずっといい感じのLinux-VServerなるものが見つかったので、忘れないように書いておく。
感じとしては、FreeBSDのJailと似たようなもの…な気がする。

・aptitudeでvserver用のカーネルとツールをインストール。
# aptitude install linux-image-2.6-vserver-powerpc \
> util-vserver \
> vserver-debiantools


・vserver用カーネルで起動するため、再起動。
# reboot


・vserver用ファイルを準備。
vserver名をmikuとし、ホスト名をmiku.v.hachune.net、ディレクトリツリーの場所を/vsv/miku、ネットワークインターフェースにeth2を使用、1番のエイリアス(eth2:1)として10.39.39.100/24を割り当てる。ループバックにはlo:1を使用する。
"--"以降はdebootstrapのオプション。ここではDebian Lennyをftp.jaist.ac.jpから取得するように設定する。

# vserver miku build \
> --hostname miku.v.hachune.net \
> --rootdir=/vsv/miku --context 39 \
> --interface 1=eth2:10.39.39.100/24 --interface 1=lo:127.0.0.1/8\
> -m debootstrap -- -d lenny -m ftp://ftp.jaist.ac.jp/pub/Linux/Debian/


…これだけ。
後は、通常のDebian同様、起動して入ってサーバを設定する。
日本語を使用したい場合はaptitude install localesするといい。
・vserverを開始
# vserver miku start
・vserverを停止
# vserver miku stop
・vserverに入る
# vserver miku enter
・vserverの状態を確認
# vserver miku status
・vserverを削除
# vserver miku delete


詳しくはmanのvserver、verver-build、vserver-statあたりを参考にすると良いらしい。
一部デバイスの関係で正しく動作しないアプリケーションがあるようだが、chrootだけよりいい感じ。
基本システムのみなので、インストール直後の容量が252MBと、かなり小さめなのも嬉しい。
Mac Mini G4では、XenやVMwareが使えないしな…。

linux-vserver.org
http://linux-vserver.org/


※追記
動くものと動かないものは以下のとおり。

動作確認:
bind9
apache

動作せず:
OpenVPN: /dev/net/tunが無いため不可。
dhcp3-server: eth2:1を正しく認識しない…?


その他必要そうな設定
・TimeZoneの設定
# dpkg-reconfigure tzdata

・digが必要な場合
# aptitude install dnsutils

2010年3月5日金曜日

OpenBSDのカーネルを再構築

これまた忘れそうなので書いておく。


・適当なところからカーネルのソース等を持ってきておく。
今回は、以下の4つを取得。
ftp://ftp.jaist.ac.jp/pub/OpenBSD/4.6/src.tar.gz
ftp://ftp.jaist.ac.jp/pub/OpenBSD/4.6/sys.tar.gz
ftp://ftp.jaist.ac.jp/pub/openBSD/4.6/ports.tar.gz
ftp://ftp.jaist.ac.jp/pub/OpenBSD/4.6/xenocara.tar.gz


・ダウンロードしたファイルを展開する。
# cd /usr/src
# tar xzf /home/miku/sys.tar.gz
# tar xzf /home/miku/src.tar.gz
# cd /usr
# tar xzf /home/miku/xenocara.tar.gz
# tar xzf /home/miku/ports.tar.gz


・カーネルをビルド
# cd /usr/src/sys/arch/i386/conf/
# cp GENERIC.MP HACHUNE
→カーネル設定の編集はここで。
MPカーネル(マルチプロセッサ用のカーネル)の設定は、殆どがGENERICカーネルをincludeしたものなので、細かい設定はGENERICを編集して変更する。

# config HACHUNE
Don't forget to run "make depend"
# cd ../compile/HACHUNE
# make depend
# make
→ EeePC(Atom N270、DDR2-667 2GB、20GB IDE-USB HDD)だと、大体20〜30分位で終了。

・Buildしたカーネルをインストール(古いものをbsd.oldとしてとっておく)
# mv /bsd /bsd.old
# cp bsd /bsd

・再起動
# reboot
→もしコケたらブートローダーでbsd.oldを指定して起動


・ユーザーランドのビルド
# cd /usr/src
# make obj
# make build
→ カーネルのビルドよりずーーっと時間が掛かるのでゆっくり待つ。

・再起動
# reboot



…と、ここまでやっていたHDDがクラッシュ。
実験用HDDだからまぁ良いのだが、やっぱり凹むな…

2010年2月28日日曜日

DebianでNFSサーバ&クライアント

ググれば大量に出てくるものを書いてもなんかなぁ...と思いつつも、
そんなことを考えていると全然Blogが書けないということに気がついたので、もう遠慮なく書くことにする。

今回は、かがみねサーバ(kagamine.h.hachune.net)の/home/mikuをめぐりねサーバ(megurine.h.hachune.net)の/home/mikuにマウントする。

まず、かがみねサーバ(NFS Server)の設定。
% sudo aptitude install nfs-kernel-server
% sudo vi /etc/exports
で、以下を追加する。
/home/miku *.h.hachune.net(ro,sync,no_subtree_check)


・ディレクトリをエクスポート(再エクスポート)する。
% sudo exportfs -ar
(nfs-kernel-serverを再起動する方法もある)

・公開できているか確認する。
% showmount -e


次に、めぐりねサーバ(NFS Client)の設定を行う。
/etc/fstabに以下を追加し、sudo mount -aする。
kagamine.h.hachune.net:/home/miku /home/miku nfs ro,sync 0 0

これでマウントできた。
サーバ側でshowmount -aコマンドを打つと、マウント状況が確認できる。
簡単だけれど、セキュアではないな…


/etc/exportsの書式は、man exports、
/etc/fstabのNFS関連の情報は、man nfs、
NFSエクスポートリスト操作コマンドexportfsの情報は、man exportfs
マウント情報確認コマンドshowmountの情報は、man showmount
を見ると良い。

Ruby1.9.1のcursesでUTF-8文字列を表示

RubyのCursesでプレイリスト操作ツールを作成しようとしたところ、文字化けして全然使い物にならないということが判明。ついでなので1.9.1にパッチを当ててビルドしてみることにする。

・ext/curses/curses.cを編集

追加:
+ #include "locale.h"

Init_curses関数内にsetlocaleを追加:
Init_curses()
{
+ setlocale(LC_ALL, "");


・ext/curses/extconf.rbを編集(ncurseswを探すようにする)

削除:
-if have_header(*curses=%w"ncurses.h") and have_library("ncurses", "initscr")
追加:
+if have_header(*curses=%w"ncurses.h") and
+ ( have_library("ncursesw", "initscr") or have_library("ncurses", "initscr") )
+ make=true
削除:
-elsif have_header(*curses=%w"ncurses/curses.h") and have_library("ncurses", "initscr")
追加:
+elsif have_header(*curses=%w"ncurses/curses.h") and
+ ( have_library("ncursesw", "initscr") or have_library("ncurses", "initscr") )
+ make=true


ruby-1.9.1-p378.tar.bz2をダウンロード
・ libncursesw-devをaptからインストール
% sudo aptitude install libncursesw-dev

・ビルド。-O2だと何故か途中でコケるらしいので、-O3にする。
% optflags="-O3 -pipe" ./configure --prefix=/usr/ruby19 --program-suffix=19

2010年2月14日日曜日

はちゅね転送サービス 開始!

以前勢いで取得したhachune.netドメインを使用し、URL転送サービスを作ってみた。

例えば、
otomania.hachune.netにアクセスが来たら、Otomaniaさんのページhttp://www.otomania.netに転送する
pocopoco.hachune.netにアクセスが来たら、たまごさんのページhttp://www.pocopoco.ccに転送する
twitter.hachune.netにアクセスが来たら、私のTwitterページhttps://twitter.com/Phenomerに転送する
といったことができます。

「サーバを間借りして作ったサイトに、分かりやすい名前が欲しい!」
「自分のボカロなサイト・ブログに分かりやすい別名を付けたい!」
などといった時に使えるかと思います。


詳細は以下からどうぞ。
http://hachune.net/hachune-forward.html


.comがドメイン広告になってるな…なんか寂しい。

2010年2月9日火曜日

CでOpenMPを使ってみる

せっかくマルチコアCPUがあることだし、全コアを全力で使えるプログラムを作ってみたいと考えていたが、いろいろ面倒で諦めがちだった。しかし、C/C++にはOpenMPという便利なものがあると聞いて、調べみたところ、本当に便利だったのでここに纏めてみる。


OpenMPを利用するには、GCC 4.2以降が必要で、コンパイル時に-fopenmpオプションを付ける必要がある。
% gcc openmp_test.c -o openmp_test -fopenmp

また、今回OpenMP関連で使用した関数とその役割は以下のとおり。
omp_get_thread_num() … 現在実行されているスレッドの番号を返す
omp_set_num_threads(10) … スレッド数を10に指定(通常はCPUコア数から自動的に割り振られる)


まずは一番簡単なスレッド作成方法。
スレッド処理したい関数の前に#pragma omp parallelを書くだけ。

#include<stdio.h>

int main(void){
int i;

#pragma omp parallel
for(i=0; i<20; i++){
printf("Thread %d : %d\n", omp_get_thread_num(), i);
}
return 0;
}


これをコンパイルし実行すると、

miku@kagamine:~/c-lang$ ./openmp_1
Thread 0 : 0
Thread 0 : 1
Thread 0 : 2
Thread 0 : 3
Thread 0 : 4
Thread 1 : 0
Thread 1 : 1
Thread 1 : 2
Thread 1 : 3
Thread 1 : 4

となったり、

miku@kagamine:~/c-lang$ ./openmp_1
Thread 1 : 0
Thread 1 : 1
Thread 1 : 2
Thread 1 : 3
Thread 1 : 4
Thread 0 : 0

となったりする。なにやら同時に処理されているように見え、スレッドの実験としては成功していることが分かる。
しかし、結果が安定していないため、このままではあまり使い物にならない。
開始したスレッド全てから変数iが参照され、変更されるためこうなってしまう。



そこで、変数iをスレッド内でプライベートに使うようにしてみる。

#include<stdio.h>

int main(void){
int i;

// 変数iをスレッド内プライベートとして渡し、スレッドを開始させる
#pragma omp parallel private(i)
for(i=0; i<3; i++){
printf("Thread %d : %d\n", omp_get_thread_num(), i);
}

return 0;
}

これを実行すると…

miku@kagamine:~/c-lang$ ./openmp_2
Thread 0 : 0
Thread 1 : 0
Thread 1 : 1
Thread 1 : 2
Thread 0 : 1
Thread 0 : 2

iの値はそのスレッド内のみの値として扱われ、
スレッド毎にi++されていることが分かる。



通常、全スレッドが全く同じ処理を繰り返しても意味が無い。
そこで、グローバルな変数iを操作するときのみ、排他処理を行わせる。

#include<stdio.h>

// 変数iをグローバルとして渡すが、printfとi++の部分を排他動作させる
int main(void){
int i;

i = 0;
#pragma omp parallel
while (i<10){
// 排他処理部分をブロックで指定
#pragma omp critical
{
printf("Thread %d : %d\n", omp_get_thread_num(), i);
i++;
}

sleep(1);
}
return;
}

これを実行すると…

miku@kagamine:~/c-lang$ ./openmp_3
Thread 1 : 0
Thread 0 : 1
Thread 1 : 2
Thread 0 : 3
Thread 1 : 4
Thread 0 : 5
Thread 1 : 6
Thread 0 : 7
Thread 1 : 8
Thread 0 : 9

iの値が、両スレッドで1づつ増えていっているのが分かる。

ただ、このテストプログラムには問題がある。
while (i<0)の判定後、whileループの中で別スレッドがiに値を追加し、
printf()するときにiの値が10または10以上になってしまうことがある(sleep(1)を外すと頻繁に発生する)。
この辺りを、正しく処理させるようにしないと、「数回に1回だけ何故かコケる」なんて厄介なバグになってしまうので、注意したい。



何でもかんでも排他処理させてしまうと、他の関数で実行中のスレッドにまで影響が及び、何かしらの問題(デッドロック等)が発生する可能性がある。
そこで、できる限り排他処理を使わないようにしてみる。
(ついでに、しっかり4コア使ってくれるのか確かめるため、dummy関数を用意した)

#include<stdio.h>
#include<unistd.h> // usleep()
#include<stdlib.h>


// ダミー処理関数(CPUに負荷を掛ける)
void dummy(int number){
int n, i, tmp;
int array[number];
for(i=0; i<number; i++){
array[i] = i;
}

for (n=0; n<number; n++){
for (i=0; i<number - 1; i++){
if (array[i] < array[i+1])
{
tmp = array[i];
array[i] = array[i+1];
array[i+1] = tmp;
}
}
}
return;
}


// 変数iをグローバルとして渡すが、printfとi++、dummy(10000)の部分をシングルスレッド動作させる
int main(void){
int i, while_count;

i = 0;
while_count = 0;

#pragma omp parallel
while (<<100){

// ブロック内をシングルスレッド動作させる
#pragma omp single
{
printf("Thread %d : %d\n", omp_get_thread_num(), i);
i++;
dummy(10000);
}
printf("Thread %d : loop...\n", omp_get_thread_num());
usleep(10);
while_count++;
}

printf("loop Count: %d\n", while_count);
return;
}



また、「ブロック内を他のスレッドが実行中なら、ブロック内の実行をスキップする」ということも可能。

#include<stdio.h>
#include<unistd.h> // usleep()
#include<stdlib.h>


// ダミー処理関数(CPUに負荷を掛ける)
void dummy(int number){
int n, i, tmp;
int array[number];
for(i=0; i<number; i++){
array[i] = i;
}

for (n=0; n<number; n++){
for (i=0; i<number - 1; i++){
if (array[i] < array[i+1])
{
tmp = array[i];
array[i] = array[i+1];
array[i+1] = tmp;
}
}
}
return;
}


// 変数iをグローバルとして渡すが、printfとi++、dummy(10000)の部分をシングルスレッド動作させる。
// もしその部分が別スレッドで処理中ならスキップする
int main(void){
int i, while_count;

i = 0;
while_count = 0;

#pragma omp parallel
while (i<100){

// single nowait : 他のスレッドがブロック内を実行中だったらスキップ
#pragma omp single nowait
{
printf("Thread %d : %d\n", omp_get_thread_num(), i);
i++;
dummy(10000);
}
printf("Thread %d : loop...\n", omp_get_thread_num());
usleep(10);
while_count++;
}
printf("loop Count: %d\n", while_count);
return;
}


#pragma omp singleと、#pragma omp single nowaitの場合を、
実際にコンパイルして実行、比較してみると、多分違いが分かる…と思う。
また、omp_set_num_threads(スレッド数)で、スレッド数を変更しながらいろいろ試してみるのも良い。


結構長い間やっていた筈なのに、C言語のBlog投稿は今回が初めて。
やっているけど書いていないことって、かなり多いな…。

2010年1月30日土曜日

様々なOSでRAMDiskを使ってみる

/ramに32MBのRAMDiskを作る、/etc/fstabの設定を比較してみた。
実験に使用したOSは、Linux(Debian 5.0 Lenny)、FreeBSD 8.0、OpenBSD 4.6の3つ。

Linux
tmpfs /ram tmpfs rw,size=32m 0 0

FreeBSD
md /ram mfs rw,-s32m 0 0

OpenBSD
swap /ram mfs rw,-s=65536 0 0


fstabの5列目は、「dumpが必要なファイルシステムであるか」、6列目は、「起動時にfsckを行う必要のあるファイルシステムであるか」であり、RamDiskにはどちらも必要ないので、0とする。

OpenBSDは、サイズで指定するのではなく、ブロック数で指定するので、直感的には分かりづらい感じ。
(試しに-s=32mとしてみたところ、そんなサイズ知らねぇよ、と言われた)
また、65535と1ブロック少ない値を設定したところ,
mount_mfs: reduced number of fragments per cylinder group from 8184 to 8112 to enlarge last cylinder group
と言われるので、おとなしく8192で割り切れる値にしておいた方が良さそう。


コマンドだと、こんな感じ。
Linux
# mount tmpfs -o rw,size=32m /ram

FreeBSD
# mount_mfs -s 32m -o rw md /ram

OpenBSD
# mount_mfs -s 65536 -o rw swap /ram

2009年12月21日月曜日

Multi Thread Multimedia Encoder Frontendの新バージョンのAlpha版を公開

1年ぐらい前から作っていた「lameやoggでマルチスレッドエンコードするフロントエンド」を更新してみた。
更新と言っても、設計は1からやり直し、コードもすべて1から書き直しているので、新ソフトと言ってもいいような位別物になった…気が。



ただ、まだAlpha版なので、おかしい所があるかも知れない上に、Readme.txt等のドキュメント類も無し。
それでも使ってくださるという方は、以下からダウンロードしてください。
https://sites.google.com/a/g.hachune.net/mtmef/home/download/Encoder_v2.0alpha_100103.zip?attredirects=0&d=1
まだWindows版しかありません。(´・ω・`)スマソ
09.01.03
'require': No such file to load -- fileutilsとなる問題を修正しました。
ビルドに失敗していたようです…。

※主な機能追加
・GUIの改良
・ファイル単位での追加も対応(今まではフォルダ単位のみ)
・フィルタ設定のGUI化
・文字コード関連の問題が回避しやすくなった
・ID3タグなどに対応しやすいように改良
・ログ出力機能の強化


自分自身では常用できるレベルなので、後は違う環境で問題が発生しないか、しょーもないバグが無いかなどを確認後、早急にreadme.txt等のドキュメント類を完成させて、正式リリースできれば、とは思っているのだが…何時になるやら…

2009年10月31日土曜日

Ubuntu 9.10もいつの間にかリリース

入門Linux(?)として最近有名なUbuntuの最新版、Ubuntu 9.10(kermic)もいつの間にかリリースしていた。

…とりあえずVMにインストールしてみるよ(´・ω・`)


デフォルトのファイルシステムがext4になっていたり、謎の機能「Ubuntu One」が追加されていたり、デフォルトのメッセンジャーがpidginからEmpathyに、IMがSCIMからiBusに変更されていたり…
付属ソフトがコロコロ変わるってのは、初心者に優しくないような気がしなくもないのだが('A`)

あと、「結構重い」というのも…
まぁ、重いといっても、Vista初期に売られまくっていたVista必須スペック限界PC位なら普通に使えるので、まず気にならないとは思う。

EeePCをOpenSUSE 11.1からこっちに換えるべきか…悩み所だな…

VMware Player 3.0などがいつの間にかリリースされていた

仮想化ソフトで有名なVMwareの新しいバージョンが、いつの間にかリリースされていた模様。
今回のバージョンでは、今まで仮想環境が苦手としていた、DirectXやOpenGLなどの3D周りの機能の実装や、このあいだ発売したばかりのWindows 7やWindows Server 2008 R2のサポート、VMware Playerでのゲスト仮想マシンの作成が可能になった、クアッドコアに対応等、色々進化したらしい。

対XP Mode戦略…だろうか。


と言う訳で、こないだ組んだばかりで、仮想化ソフトが何も入っていなかったDebian(Kagamine-Server)に、VMware Player 3.0をインストールしてみた。

インストールは、
VMware Playerのページで、ダウンロードリンクを辿り、ユーザー登録。
・ユーザー登録後、登録したメールアドレスにメールが届くので、そのメールのダウンロードリンクから必要なファイル(私の場合は、"VMware Player for 64-bit Linux")をダウンロードしてくる。
・Linuxの場合、"VMware-Player-3.0.0-203739.x86_64.bundle"というファイルがダウンロードされるので、それに実行属性を加え、root権限で実行する。
・Linuxにしては珍しくGUIのインストーラーが起動するので、ウィザードに従いインストール。

後は、以前のバージョンや他の仮想化ソフト同様、仮想ハードウェアの設定などを行い、ゲストOSをインストールする。
3.0になってだいぶ簡単になったみたいだな…(*´Д`)




Windows Server 2008 R2上でPlayer 3 + Windows XPを動かしたところ、ユニティという機能が追加されていた。

Windows XP Mode同様に、ホストOS側にゲストOSのアプリケーションを表示することができる…らしい。
統一感の無いUIは気持ち悪いが、どうしても7やServer 2008 R2で動かなかったアプリケージョンを、XP Modeより高速かつDirectX等ありで動かせるのは、ありがたいような気もしなくはない。


VMware.com
http://www.vmware.com/jp/

2009年10月15日木曜日

RubyのFile.extnameについて

Rubyでファイルの種類を拡張子で判別しようと、File.extnameを使用してみたのだが、上手く拡張子を判別することができないことがあった。


irb(main):006:0> File.extname("01 miku.mp3")
=> ".mp3"
irb(main):007:0> File.extname("01 miku .mp3")
=> ""


拡張子の直前にスペースが含まれているとダメらしい。
自分で正規表現使って判別するしかないのか…
/.+(\..+)$/ …で良いのかな…?

半角スペースが入ってるなんてぱっと見分からず、最初物凄く悩んでしまった…(´・ω・`)



ちなみに実行環境はruby 1.8.7 (2008-08-11 patchlevel 72) [i386-mswin32]でした。

2009年9月21日月曜日

# rm -rf /を実際にやってみた

Hyper-V 2.0の動作実験としてインストールしたUbuntuが必要無くなったので、よくネタとして扱われる
# rm -rf /
を実際に実行してみた。

その結果…
rm: cannot remove root directory '/'
(´・ω・`)ショボーン



では、# rm -rf /*ではどうなるのか。



( ゚∀゚)アハハ八八ノヽノヽノヽノ \ / \/ \


ここで固まってしまい、リブート。
だが、正しく起動できる訳もなく、
GRUB loading, please wait...
Error 15

となり…(ヽ´ω`)

2009年9月17日木曜日

はつねさんがシステムに常駐して時間をお知らせしてくれるアプリ「みくろっく」を作ってみた

夏休みも今日で終わり…ということで、最後になんか作ってみようと考えたのは良いものの、大して良いアイディアが思い浮かばなかったので、以前ダイナミックDNSの自動更新ツールをWindowsサービス化したときに、実験として作っていたみくろっく(Windowsサービス版)を改良してみることにした。

機能は、
・Windowsサービスとしてシステムに常駐
・以下のタイミングで音声でお知らせ
 -システム起動時(朝、昼、夜)
 -システム終了時(朝、昼、夜)
 -毎時00分(1~12)
 -毎時15、30,45分
 -5分に1回位、ランダム
・音声にはmp3ファイルを使用可能
・複数の音声ファイルから毎回ランダムで再生することも可能



肝心のはつねさんの音声ファイルが地味に手抜きな気が…
…誰かめぐりねさんとかで作って…(´д`*)アハァ


ダウンロードは以下からどうぞ。


こちらからもダウンロード可能。
https://sites.google.com/a/g.hachune.net/mtmef/home/download/Mikulock_WS_v1.01.zip?attredirects=0


たまには大して役に立たないアプリ作ったっていいよね…(´・ω・`)


※09.09.19 追記
「サービスは予期せぬ原因により終了しました」となり落ちることがある模様なので、
修正版を連休中に作りなおします…

※09.09.20 追記
修正版を公開しました。
多分これで大丈夫…なハズ。

2009年9月6日日曜日

Windows 7 EnterpriseとWindows Server 2008 R2の評価版のアクティベーション

評価版のライセンス認証の形式が以前と変わっていたので、纏めてみる。

・10日間のアクティベーション猶予期間をslmgr.vbs -rearmコマンドで、5回リセット可能(7は2回?)
・評価ライセンスが最初から組み込まれていて、それを使ってアクティベーションすることによって180日評価可能(7は90日)



アクティベーションは、通常購入したWindowsと同じく、コントロールパネル→システムの「Windows ライセンス認証」から行うことができる。

「今すぐライセンス認証を行う場合はここをクリックしてください。」のところをクリックし…
(「プロダクトキーの変更」は不要)


「Windowsのライセンス認証の手続きを今すぐオンラインで行います」をクリック。


後は、自動でライセンス認証の手続きが行われ、問題なければ180日間評価することができる。
(画像は、以前仮想環境でWindows Server 2008 R2をライセンス認証したもの)


VistaやServer 2008の時は、評価版はライセンス認証できなかったので、期間中にも拘らずライセンス認証を何度も要求されるなど、色々気持ち悪かったな…('A`)