2009年6月30日火曜日

thread_pool

そういえば、ブログの方には、ポストしてなかったので、thread_pool のコード、ポストしときます。
コンセプトは、スレッド・イニシャル時のランタイムの初期化等を省力化する事と、スリープ時には負荷を加えない事の2点です。この設計コンセプトは、BOOST_THREAD を定義すると守られません。

 まぁ、バグがあって、終了しないとか、あるかもしれないので、そこんところはよろしくです。

thread_pool.hpp

//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Copyright (c) 2007 OKI Miyuki (oki.miyuki at gmail dot com)
//
#include <windows.h>
#include <deque>
#include <boost/thread.hpp>
#include <boost/function.hpp>

//#define BOOST_THREAD

/// ワーカ関数型
typedef boost::function<void (void*)> worker_func_t;
/// スレッドの設定関数型
typedef boost::function<void (void)> setup_func_t;

/// ワーカ情報
/*!
@brief ワーカ・ホルダ
*/
struct worker_info {
public:
worker_info() : func_(), arg_() {}
worker_info(
worker_func_t f,
void* arg
);
public:
worker_func_t func_; //!< ワーカ関数型
void* arg_; //!< 引数
};

/// ワーカ・ホルダ・キュー
typedef std::deque<worker_info> worker_queue_t;

/// 何もしない関数
void empty_func();

/// スレッド・プール・クラス
class thread_pool {
private:
size_t pool_count_; ///< スレッド・プール数
#ifdef BOOST_THREAD
boost::condition cond_;
boost::mutex mutex_;
#else
union {
HANDLE ready_[2];
struct {
HANDLE sync_; ///< キュー同期用
HANDLE free_; ///< 空き待ちシグナル
};
};
#endif
boost::thread_group threads_;
worker_queue_t queue_; ///< ワーカ・キュー
volatile bool continue_; ///< 停止通知用
setup_func_t initializer_; ///< 初期化関数
setup_func_t uninitializer_; ///< 終了化関数

private:
/// スレッド・プール関数
void pool_func();

private:
/// クラス初期化処理
void init();
/// クラス終了処理
void term();

public:
/// コンストラクタ
explicit thread_pool(
setup_func_t initializer = empty_func,
setup_func_t uninitializer = empty_func,
size_t pools = 16
);

/// デストラクタ
~thread_pool();

/// ワーカをスケジュールする
void schedule(
worker_func_t func,
void* arg
);

/// スレッド・プールを終了する
void stop();

};


thread_pool.cpp

//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Copyright (c) 2007 OKI Miyuki (oki.miyuki at gmail dot com)
//
#include <thread_pool.hpp>
#include <boost/assert.hpp>
#include <boost/bind.hpp>

//#define HNS_THREADPOOL_DEBUG
#ifdef HNS_THREADPOOL_DEBUG
#include <iostream>
#endif

worker_info::worker_info(
worker_func_t f,
void* arg
) :
func_(f),
arg_(arg)
{
}

void empty_func() {}

void thread_pool::pool_func() {
initializer_();
while( continue_ ) {
bool do_work = false;
bool do_notify = false;
worker_info worker;
{
#ifdef BOOST_THREAD
boost::mutex::scoped_lock lk(mutex_);
#else
WaitForSingleObjectEx( free_, INFINITE, FALSE );
{
WaitForSingleObjectEx( sync_, INFINITE, FALSE );
#endif
if( !queue_.empty() ) {
worker = queue_.front();
queue_.pop_front();
do_work = true;
}
do_notify = !queue_.empty();
#ifndef BOOST_THREAD
if( do_notify && continue_ ) {
SetEvent( free_ );
} else {
ResetEvent( free_ );
}
}
ReleaseMutex( sync_ );
#endif
}
#ifdef BOOST_THREAD
if( do_notify && continue_ ) {
cond_.notify_one();
}
#endif
if( do_work && continue_ ) {
worker.func_( worker.arg_ );
}
}

#ifdef HNS_THREADPOOL_DEBUG
std::cout << "pool_func LEAVE:" << GetCurrentThreadId() << std::endl;
#endif
#ifndef BOOST_THREAD
SetEvent( free_ );
#endif
uninitializer_();
}

void thread_pool::init() {
#ifndef BOOST_THREAD
sync_ = CreateMutex( NULL, FALSE, 0 );
free_ = CreateEvent( 0, TRUE, FALSE, 0 );
#endif
for( size_t i = 0; i < pool_count_; ++i ) {
threads_.create_thread( boost::bind( &thread_pool::pool_func, this ) );
}
}

void thread_pool::term() {
continue_ = false;
#ifdef BOOST_THREAD
cond_.notify_all();
threads_.join_all();
#else
if( free_ && sync_ ) {
SetEvent( free_ );
threads_.join_all();
}
if( sync_ ) {
CloseHandle( sync_ );
sync_ = 0;
}
if( free_ ) {
CloseHandle( free_ );
free_ = 0;
}
#endif
}

thread_pool::thread_pool(
setup_func_t initializer,
setup_func_t uninitializer,
size_t pools
) :
initializer_(initializer),
uninitializer_(uninitializer),
pool_count_(pools),
#ifdef BOOST_THREAD
cond_(),
#else
sync_(),
free_(),
#endif
threads_(),
continue_(true)
{
init();
}

thread_pool::~thread_pool() {
term();
}

void thread_pool::stop() {
term();
}

void thread_pool::schedule(
worker_func_t func,
void* arg
) {
#ifdef BOOST_THREAD
{
boost::mutex::scoped_lock lk( mutex_ );
#else
WaitForSingleObjectEx( sync_, INFINITE, FALSE );
#endif
if( continue_ ) {
queue_.push_back( worker_info( func, arg ) );
SetEvent( free_ );
}
#ifdef BOOST_THREAD
}
cond_.notify_one();
#else
ReleaseMutex( sync_ );
#endif
}

#ifdef HNS_THREADPOOL_DEBUG

#include <boost/lexical_cast.hpp>
#include <boost/random.hpp>
#include <ctime>

// random generator class
/*!
@note Default random generator is too poor.
*/
struct random_generator {
private:
mutable boost::mt19937 mt_gen_;
public:
random_generator() :
mt_gen_(static_cast<unsigned long>(std::time(0)))
{}

int operator () (int n) const {
// Using mod is not uniform. but behavior is less.
return (mt_gen_() % n);
}
};

void test( void* arg ) {
std::cout << ">> test(" << (int)arg << ":" << GetCurrentThreadId() << ");" << std::endl;
Sleep( ((int)arg) * 250 );
std::cout << "<< test(" << (int)arg << ":" << GetCurrentThreadId() << ");" << std::endl;
}


void main() {
thread_pool pool;
random_generator rg;

for( int i = 0; i < 20; ++i ) {
pool.schedule( test, (void*)(rg(12)) );
pool.schedule( test, (void*)(rg(12)) );
pool.schedule( test, (void*)(rg(12)) );
pool.schedule( test, (void*)(rg(12)) );
pool.schedule( test, (void*)(rg(12)) );
pool.schedule( test, (void*)(rg(12)) );
pool.schedule( test, (void*)(rg(12)) );
std::cout << "...zzZ" << std::endl;
if( i < 12 ) Sleep( 2000 + rg(4000) );
std::cout << "Zzz..." << std::endl;
if( i == 10 ) pool.stop();
}
}

#endif



追記:2009/07/21 WaitForMutipleObjectsEx を分離する形に修正
 スケジューリングの関数自体と、スレッドの関数自体がスレッド・プールの同期オブジェクトをダイレクトに利用するため、ユーザ指定スレッドと複合してデッドロックを起こす可能性があるので、関数のスケジューラには、代理スレッドを立てた方が良いかと思案しているが、取り入れるには至っていない。

追記:2009/07/28 終了時のイベントの取り扱いが不味いのを修正。
 stop 関数を追加。
 テスト・ケースを修正
追記:2009/08/05 term 時のcontinue_ に対する同期保護は不要なので削除

2009年6月29日月曜日

ぼやっきー

 WANで連帯するのにさー、動的IPって何だよ・・・って憤慨してさー、まあ、対応しましたよ・・・。当然、動的IPに対して配信すべき内容があるけど、そこはまぁ、ホテル暮らしの人から連絡があったら、配信がエラーにならない限り、そのホテルに配信するって事で、対応しましたとも・・・。
でさ、今日聞いた話だと、今度はルータから接続されているサーバが無線LANで接続されてるんだとさ・・・。だもんで、時々リンクが切れてさー、ホテル暮らしの人への配信がエラーになるんですとさーー。知るカーーーーーーーー!ボケーーーーー。
そんでさー、まあ、何かトリガーがあれば、やっぱり、俺、このホテルで暮らしてます・・・って、再配信をするみたいなんだけどさ、配信が止まった間に溜まった更新もあるだろうし、無線LANなもんで、通信も遅いんだってさーーーー。あたりまえじゃーーーーーーーー。

追記:サーバを置いて、Twitter みたいにプルかよっ!おまえは、ブラウザ・サーバかっ!

boost::random を標準で利用

こういう、しょうもないものなら、覚えがあるので、ポストしてみますた。
まあ、こんなページもあるみたいですが・・・。標準のものよりは随分まともで、妥協できる感じではないかと思います。

#ifndef RANDOM_GENERATOR_HPP
#define RANDOM_GENERATOR_HPP
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Copyright (c) 2009 OKI Miyuki (oki at hunes dot co dot jp)
//

#include <ctime>
#include <boost/random.hpp>

/// random generator class
/*!
  @note Default random generator is too poor.
*/
struct random_generator {
private:
  boost::mt19937 mt_gen_;
public:
  random_generator() : 
    mt_gen_(static_cast<unsigned long>(std::time(0))) 
  {}

  int operator () (int n) {
    // Using mod is not uniform. but behavior is less.
    return (mt_gen_() % n);
  }
};


#endif // RANDOM_GENERATOR_HPP

2009年6月26日金曜日

まつもとゆきひろ コードの世界 感想

 アデノウィルスにやられて喉がイガイガして眠れません。そんな訳で感想を書くことに…。

 「まつもとゆきひろ コードの世界」

 まつもとさん、私より1年上で、わりと近いんですね…。綺麗にまとまっていると思います。さすがに扱っているジャンルも広い…。スクリプト言語を開発すれば、どれもぶち当たる問題なのかも?

 第7章 文字コードについて、すごい綺麗にまとまっていて、この章だけでも読む価値があると感じました。次いで、第12章 時間を扱うプログラムについて、も面白いと思います。ユリウス暦からグレゴリオ暦への改暦のタイミング表が載っています。私は未だに私達が歴史の教科書で教えられた年表は何暦なのか疑問に感じているところです。西暦ってグレゴリオ暦の事?でも、ヨーロッパじゃ改暦前はユリウス暦でしかない感じなんです。第10章 プログラミングの高速化と並列化について の Revactor が boost::asio チック(どちらがどうとかは無いです)で、最近の流れというものを感じました。第13章 データの永続化について の XML の部分も同感です。付け加えさせてもらうと、XMLの仕様上、制約をかけるという部分が、スキーマの設計に影響している部分は、ダーティで変だと感じてます。普通の言語でクラスを設計し継承していくと、機能を拡張する形になるのに、XMLの場合は要素数を減らす継承とか、とかく妙なスキーマが目立つ気がしてます。Object Prevalence (オブジェクトの保存)が、個人的には面白かったです。ライブラリではありませんが、自分ではマルチ・スレッドに対応して、トランザクションには対応していない関係で実装しているものがあり、現在、そこの部分の実装の変更を考えて、実行に移しつつあるからです。ジャーナル・ログという用語が出てきますが、RDB で言う WAL(先行書出ログ)の事かと思います。あと、Erlang は、どんな感覚の言語なのかが書いてあり、いつかは突っ込んでみたいと思っていたので、助かりました。

自分の場合、スクリプト言語よりもC++の方が書きやすいという感覚なので、若干の違和感はありましたが、全体的に読みやすかったです。それだけ、まつもとさんの味が出ているという事なのだと思います。

2009年6月25日木曜日

東京出張

 全国SaaSベンダー連合会という会合に参加するために東京に出張していました。もう少しベンダー間の連帯とかあった方が良いような感じがしました。正直、札幌SaaSビジネス研究会の方が中身は上な感じです。もうちょい交流があるだろうと思って資料も作成して行ったのですが、皆さんサッサと解散していなくなってしまったので、1枚も使わずに終了しました。軽いデモも見せられるように重いノートパソコンも持ち歩いていたのに無駄骨でした。しばらく展開に進展が無さそうなので、次回の会合は欠席してもいいのかも…。
 全く収穫が無かったわけではありません。仮想化技術で、Palallels さんの事例は知りませんでした。何でもカーネルをドライバも含めて専用で仮想化として作成しているので、メモリやCPUなどのリソースをハードウェア・スペック内においてゲストOS間で自然と動的にスケール・アウトする事になり(と私は解釈した)、簡易なB2C用途には向いているという事でした。もうひとつは、富士通さんのプレゼンにより、VMWare や Hyper-v も最新では進化しており、ノンストップでハードウェア間を移動できる(Hyper-v は、もしかしたら、そこまでは出来なかったかも)そうです。今後は、動的にCPUなどがスケールアウトできるかどうか?が課題なんだそうです。GAEは動的にスケールアウトするので、そういう面ではGAEは進んでいると言えそうです。
 設計が絡んできますが、MapReduce ならぬ、TaskReduce(BigTableに実行モジュールを保存しておき、Task名により実行モジュールを動的にロードして実行するというような仕組み)なモジュールがあれば、案外、負荷のかかる処理に対して自然と動的にスケールアウトできるかも?などと考えてしまいました(もしかしてGAEはズバリそれに近いのかも?)。
 もひとつ、Sun の方が、Oracleとの関係で今後どう展開していくのか、まだわからないと冗談交じりにプレゼンされていました。クラウドのプラットフォーム間での引越しも今後問題になってくるだろうという事で、オープンなプラットフォーム(Javaやオープン・オフィスなど)を挙げられていました。オープン・オフィスのファイル・メニュー「Save as Cloud...」には、納得しました。エンド・ユーザさんの中には、単に文書管理+検索だけで十分という所も多いんですよね…(WebDavがまともなら苦労しない)。Amazon のように Openサービスに強いクラウドもあれば、イントラネットの延長線上にある Hosted Private なクラウドもある、という話が印象的でした。

2009年6月24日水曜日

天才!成功する人々の法則 感想

鉄は熱いうちに叩け!ちょっと最近、ちょこまかと、とっかえひっかえ本を読んでいて、すぐに感想を書かなかったせいで、何を書きたかったのか忘れてしまって、何かトリガーが実行されないと出てこなくなりました。そんな反省もこめて感想です。

 「天才!成功する人々の法則」本書は、人が成功するための条件を分析したものだと思います。逆を返せば、成功するために、どのような事をしたら良いかを説いた本でもあります。いくつかの条件は、自力で整える事が可能ですが、いくつかの条件は社会的に整えてあげないと実現が難しいものもあります。教育制度や教育プログラムなど、本書を読めば考え方が変わると感じました。

 本書では、努力すれば誰でも天才になれるような印象を与えていますが、この点に関しては、私は意見を異にします。人には向き不向きがあり、例え1万時間を費やそうとも、向いていないものに対しては才能が開花しない場合があるだろうと思っています。しかし、一番重要なポイントは、好きな事。好きであれば、向き不向きもあまり関係ありません。好きであれば、まず間違いなく向いています。蛇足ですが、自分は凡人だから天才には適わないと思うのは早計ではないか?と、このごろ思うようになりました。生命は、足りない部分を何らかの形で補うのではないか?という仮説です。天才ならば、何でもすぐに理解して、さっさと解決してしまう。でも凡人には、そんな真似はできないけども、何らかの代替案が用意されている気がしてます。

 数学の問題を解く時間の話は面白かったです。ちょうど今、巡回セールスマン問題をやっていたところなので、遺伝的アルゴリズム(GA)を思い出しました。場当たり的にいろんな考えを試して、その試行錯誤がある瞬間に解へと導くという話は、まさにGAのようです。局所解からの脱出には、ある程度時間がかかります。時間を費やせば、よりよい解へ到達する確率も高くなるのです。

 総じて面白かったので、著者の別の本を読みたくなりました。

追記:映画「アマデウス」は、1万時間を費やしても作曲の才能を得られなかったサリエリの物語という見方もできるかも?1万時間を音楽に費やした彼にはモーツアルトの素晴らしさが誰よりも理解できる。そして、1万時間を音楽に費やしたにも関わらず、神は彼に作曲の才能を開花する事を許さなかった…。

2009年6月23日火曜日

プロポリス

うちの坊ちゃんが、アデノウィルスに感染してしまったとばっちりを受けて、喉が痛かったのですが、養蜂所から買った蜂蜜におまけとして付いてきたプロポリスという成分の入った「のど飴」を舐めたら、痛みが、ものすごく良くなった…。正直、出掛けのルゴールを喉にスプレーよりも効く。プロポリス、結構いけるかも?

2009年6月22日月曜日

delphi で syslog 送信

ここの続き
Delphi のデバッグに四苦八苦している状況を助けるために、Delphi 版の syslog 送信ユニットを作成しました。と言っても、かなり手抜きです。ポートが合っているだけで、syslog か?というツッコミは無しで・・・。
// syslogc.pas
unit syslogc;

interface

uses Windows, WinSock, SysUtils;

procedure udp_send( msg: string );

implementation

procedure udp_send( msg: string );
var
  len: integer;
  buf: array [0..4096] of Char;
  wsaData: TWSAData;
  sock:    TSocket;
  addr:    TSockAddrIn;
begin
  len := Length(msg);
  strpcopy( buf, msg );  // 手抜き
  if 0 = WSAStartup( MakeWord(2,0), wsaData ) then begin
    sock := socket( AF_INET, SOCK_DGRAM, 0 );
    if sock <> INVALID_SOCKET then begin
      addr.sin_family := AF_INET;
      addr.sin_port   := htons(514);
      addr.sin_addr.S_addr := inet_addr(PChar('127.0.0.1'));
      sendto( sock, buf, len, 0, addr, sizeof(addr) );
    end;
    WSACleanup();
  end;
end;

end.

2009年6月21日日曜日

時鮭

温暖化の影響で海流が変わったのか、白鮭が大漁で値崩れしているらしい。関係あるのか無いのかわかりませんが、近くの魚屋さんに時鮭が売っていたので、買ってきました。
いつもは、銀鮭の半身を買ってきてやるのですが、今回は、切り身で・・・。骨を取り除いて、ヒマラヤの塩をふりかけます。塩加減は、何度やっても難しい。
塩をしてから、30分ほど放置プレーして、塩が馴染むのを待ちます…。水気をとって、ラップにくるんで冷凍庫へ

巡回セールスマン問題を解く(9)

 しつこく、現行アルゴリズムの改善に取り組んでいますが、奥が深い...orz
少しでも最適解に近づこうと、いろいろ導入してみるのだが、計算量を増やしたからと言って結果が改善されるとは限らない。いやー、まじ、奥が深すぎ。

2009年6月20日土曜日

ディレーラ(自転車)

 うーーん、はやくもリア・ディレーラ(Simano Deore)のシフト・チェンジ感が気になってきてしまった…。いや、いくら調整しても、中間のギア変速が、Hi -> Lo の時だけうまくいかないのだ…。ゴミとかが詰まって、左右方向の移動が阻害されているのだろうか?と思って、油を挿してコキコキしたけど、いまいち…。
 そして、もうちょい Lo 側のギアが欲しくなってしまった…。

2009年6月19日金曜日

勤務中のブログ

 なんか、欠勤中の時間帯にブログを書いただけで、罰せられる会社があるみたいなんですよ…。一方で、ブログを書くことを必須条件とする会社もあるみたいなんですよ…。普通の仕事ならいざ知らず、ITの仕事をしていて、いろんなサービスに手をださないというのは、プログラマとしてどうかな?と、思ってしまいます。私だったら喜んじゃうよ。そりゃ、度を越えて本職を忘れてまで没頭していたら、ちょー、おまえ仕事しろよ…と注意するでしょうけど…。

2009年6月18日木曜日

ネットはツール

 夢を見すぎなのではないかな?と感じる事があります。本質とは違うのではないかな?と感じる事があります。
 例えば、BBSで誹謗中傷があるからBBSはダメだ。とか、運用の問題を、技術の問題にすりかえられる事が多いのではないでしょうか?
 ネットを活用すれば、夢が広がる。確かに規模の拡大やスピード化は図れる事でしょう。しかし、所詮、ネットはツールなのです。扱うのは、人なのです。ここだけを見て残念がってもしょうがないと感じます。
 日本の場合は、市民活動というものが弱いのだと思います。ネットうんぬんの前に、そういった土壌の改善が必要だと思います。規模の問題であり、知らないだけで日本にも様々な活動をしている人がいると思います。こういう人達をサポートする仕組みとサービスを提案すれば良いのではないでしょうか?ボランティア精神だけでは、やっていけません。そして、日々の生活にゆとりがなければ、そういった事をする余裕は生まれません。自ら何もなくても施しをできるのは、聖人君子のみです。凡人が施しをするためには、施しできる時間的余裕と金銭的余裕が必要です。

 オープン・ソースという表現は、微妙なのかもしれません。プログラミングという観点でのオープン・ソースで見れば、Google は、検索アルゴリズムを公開していませんし、Google Earth のソースも公開していません。何を公開して、何を公開しないかは、ちゃんと考えた上で競争しているのです。私の知っているオープン・ソース戦略の一つに、どうせ底辺にいるからオープン・ソースに出資して、そのプログラムを活用してデータを売ってやろうというものもありました。オープン・ソースなビジネスモデルを考え出さないと、よほどの事がない限り厳しい気がします。firefoxは、検索エンジンからお金をもらって成功していると感じます。Redhat は黒字なのでしょうか? Ubuntu もようやくトントンなレベルに到達したという話らしいし…。正直、オープン・ソースが何者なのか、未だにわからないのです。ある面では素晴らしいのですが、一方では何が素晴らしいのかさっぱりわかりません。オープンソースに加担して、自分が死んでしまっては元も子もないのです。(しかし、こうやって考えてみると、ある意味 GNU は凄いですね…。)
 私が関わりたい分野は、何を作るにも必ず必要になる基礎的な分野=ライブラリであったり、生産消費者的な分野のみです。よって、GPL という発想は皆無です。自分の仕事と競合する分野でオープン・ソースに積極的に加担しようという考えは、今のところ持っていません。それは、Google も同意見だと思います。仕事を引退したら足かせは外れるのでしょうけど、競合分野は別の話かな…?

2009年6月17日水曜日

vc manifest のデフォルト

  Visual Studio でコンパイルした場合と、nmake を使って手動でコンパイルした場合に、DLL が不整合を起こしているような感じなので、depends.exe で、DLL の状態を追ってみた。
mt.exe を駆使して、アセンブリの情報を DLL に埋め込むのは
C:> mt -manifest hoge.dll.manifest -outputresource:hoge.dll;2
という感じでいけるという事がわかったのだけども、デフォルトで作成される hoge.dll.manifest の中身がいただけない。
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
</assembly>

vc9 は sp1 なので、version='9.0.30729.1' というようになっていなければならないのである。これ、毎回手動で直せって事?どうにも、この辺の情報がよくわからなくて腹が立つ。

 何が起こっているか?推理しているところ・・・。
zlib は Visual Studio でコンパイルしたから、msvcr90.dll は 9.0.30729.1 っぽい。
それに対して libtiff では nmake でコンパイルし、mt うんぬんしたらか、msvcr90.dll と msvcp90.dll が 9.0.21022.8 っぽい。
結果、コンフリクトして msvcp90.dll が見つかりまへん・・・と、なっているのではないか?それっぽい痕跡が、ここ

 他にも、共通言語ランタイムを有効にして開発している場合に、Visual Studio で UNICODE を指定しようが、マルチバイトを指定しようが、問答無用で UNICODE が選定されてしまい、std::ifstream が問答無用で ワイド・キャラの変換をかけるみたいなのも、むかつく。

どんな時代もサバイバルする会社の「社長力」養成講座 感想

 はじめに断っておきますが、私自身、経営を目指そうと考えた事はありません。しかし、今の時代において社会人に要求されるスキルは、社長力だと感じるのです。

どんな時代もサバイバルする会社の「社長力」養成講座

  1. ストラテジー力
  2. マーケティング力
  3. ヒューマンリソース・マネジメント力
  4. 会計力
  5. リーダーシップと人間力
というような構成になっています。ストラテジー力では、経営という仕事について書かれています。自社に当てはめてみると、以下のまずい点が当てはまっていました。

  • 管理=経営と考えている
  • 社内第一主義に陥っている
  • 目標よりも目的、というよりも漠然としすぎ
マーケティング力では、自社には、戦略が足りない感じがしました。

ヒューマンリソース・マネジメント力では、方針と教育が徹底的に抜けている感じがしました。方針と教育は私も自社に対して指摘していた事項であり、もっと教育に重点を置きたいところだと改めて認識しました。しかし、時間が足りません。利益率・売り上げ共に下がっているので、負のスパイラルに陥っている気がします。先日、そろそろプログラミング・スキル自体は上がってきた2人に、「リファクタリングープログラムの体質改善テクニック」をやらせようと、勉強会を伝えましたが、業務が激詰まっているので、できる時間がないと言われてしまいました。確かに詰まっていて余裕は無いのかも・・・。ほっといても、こういう本を読むような人種は稀少価値があるのかもしれません。

会計力は、頭が埴輪になりました。お金計算に弱いわけではないのですが、興味の少ない話を読んでも、あまりピンときません。でも、ROEよりもROAというのが印象に残りました。どちらにせよ、今の時代に経営をするには、自己資本によるキャッシュフローが大切だと思います。

リーダーシップと人間力、いろいろ書かれてありますが、人それぞれスタイルがあって単純ではない感じがします。

なぜ、今の時代に社会人に要求されるスキルが「社長力」だと感じるのか?それは、情報革命により、増し分で儲ける事が難しくなった、表面上の差別化が難しくなった、等により、社員も経営に参加しなければ戦うのが困難になってきたからだと思います。

本書は、とても面白かったです。そして、ありきたりかもしれませんが、ためになると思います。

2009年6月13日土曜日

自転車通勤のすすめ(2)

 さて、いざ自転車通勤を始めようと決心したとして、どんな自転車を選ぶべきでしょうか?通勤距離にもよりますが、3km 程度までならママチャリに乗ろうが、折りたたみ自転車に乗ろうが、どうとでもなると思います。3km以上漕ぐつもりであるならば、機動力の高い自転車を選定すべきです。どのようなルートを通るのか、おおまかにでも一度検討してみてください。歩道と車道の段差が高いままになっていないか?車道を走るスペースが十分にあるか?道路はガタガタになっていないか?農道を走るか?砂利道を走るか?こういった要素を調査する必要があると思います。
 理想は、ロード・タイプの自転車で通勤する事です。しかし、これには、「ほぼ全工程にわたって車道を走れるならば」という条件が付きます。この条件を満たせない場合には、クロス・バイクを選択します。私は歩道も走るし、少しガタガタする道も走るので、クロス・バイク(下記写真)を選定しました。
 いやいや、もっとガタガタする道を走り続けるんだよ!という方は、マウンテン・バイクを選定するしか無いでしょう。しかし、マウンテン・バイクっぽいクロス・バイクもありますので、自転車屋さんに相談すると良いと思います。

 自分の自転車の特徴を紹介する事にします。自転車屋さんに長距離走り、段差のある歩道も走ると伝えたので、タイヤの口径は大きく、幅は細いです。前にも書きましたが、ビアンキ・パッソという自転車です。機動力が高くて気持ち良いです。折りたたみ自転車、ママチャリ、マウンテンバイク、似非ロード・タイプ、スポーツ自転車・・・必死こいて漕いでるのを尻目に楽に追い越していけます。自転車によって、こんなに機動力に差が出るものなのか!という感じです。
 下記写真は、前輪のサスペンションです。赤いレバーで、サスペンションをロック・アンロックできます。ガタガタする所ではアンロックし、車道ではロックしています。黒いネジのような部分で、サスペンションの固さを調整します。ロックした場合、同じ労力で時速2kmぐらいの差があると思います。たまに違うルートを通って、路面状況がひどくて、こりゃかなわん・・・と思った場合には、サスペンションを緩めます。慣れると自転車に乗りながら調整できます。

 速度計を付けて、Intelligence +1 してます。
 リュックを背負って通勤していたのですが、背中が暑くなり蒸れて、このままでは夏を乗り切れないだろうという事で、リア・キャリアを取り付けました。TOPEAK の MTX-EXP (TOPEAKのキャリアでないと付きません)です。トランザクション処理(上)(下)も持ち運べます。このリア・キャリアですが、サドルに止めるタイプを買いましたが、太ももにレバーが当たります。なので、ふとももと干渉しないようにレバーを下にずらしていますが、今度は、走っているうちにどちらかのサイドフレームが後輪に当たりそうになってくるので、リア・キャリアは、完全に固定するタイプを選択した方が良いと思います。
 買った時には自転車屋さんに調整してもらっていても、ギアの調整等をしなければならない日がやってきます。その時に後輪を回せないと調整ができないので、自転車用スタンドも必要になるでしょう。自転車屋さんの談によると、挟み込むタイプよりも便利な MINURA DS-510 が良いとの事でした。チェーン用の油には、10年以上前インライン・スケート用に買ったフィニッシュ・ラインというテフロン入りのものを使ってます。尚、調整に関する情報は無印のページが充実してました。
 当初、ヘルメットを買う予定は、あまりありませんでした。しかし、向かい風が多くて閉口し、ヘルメットを入手する事にしました。Agility +1 、Armor Point -3 。風の影響は大きいです。平地で向かい風だと時速 25km ぐらいしか出せないのに、追い風だと時速 40kmぐらい出せたりします。空気抵抗が少なくなりそうで、そこそこ安いものを選定しました。自転車競技をするわけじゃないので、数百グラム軽くしても意味がありません。
 ズボンの裾が絡まないように反射板つきのベルトと、怪我防止のグローブです。Armor Point -2。
特に、グローブは重要です。手のひらをガードしないと、こけた時に致命傷を負いかねません。(高校の時に坂道で自転車転倒して、グローブがズタズタになったけど、おかげで助かったという経験をしています)
 安全装備としてライトは付けてください。無灯火で夜間に走るのは違反です。そして、危ないです。

 どれぐらいのピッチで漕げば良いのか?調べると100ピッチ/分ぐらいのようです。しかし、最初は体力が無いので回転数をあげる事ができません。また、歳によっては瞬発力が低下して回転数をあげる事ができません。区間を決めてギアを軽くして回転数をあげて漕ぐようにしてみると良いと思います。
 毎日運動するから、すぐに痩せるだろと期待しても、そうは問屋が卸しません。効果のほどは疑問もありますが、ここの情報がほんとうっぽいので、クエン酸を導入する事にしました。

自転車通勤のすすめ(1)

 まぁ、今更、自転車通勤などをすすめなくても、15年周期の自転車ブームで、それも空前絶後のブームなのだそうである。
 器じゃなかったみたいだ…の麻生首相が断行した定額給付金、これ、何か?つうと、私の息子が払うべきお金です。そう、血吸うたろか?おまえの血、吸うたろか?なのです。今後、少子高齢化により医療費は増大し、国家の歳出が増えていくでしょう。それを防止する手段のひとつが、自転車通勤なのです。
 数年前までは、週に1回運動をしていました。しかし、ほぼ毎日運動をするのと、週に1回運動をするのとでは、決定的に違います。ここ3年ぐらいは、ほとんど運動する時間が取れなくなっていました。そうすると、体にどういう変化が起こっていたか?自転車通勤を始めて痛感しました。脂肪を燃焼させる新陳代謝機能が極端に落ちていました。普通であれば長時間運動すると体が脂肪を燃焼させてエネルギーを筋肉に供給するはずなのですが、自転車通勤を始めたばかりの時は、通勤中盤から体中がエネルギー不足で動かなくなりました。結果、会社や家に着いた直後は、青息吐息。このまま放置していれば、数年~十数年後には病気になっていたかもしれません。
 医療費を減らす究極の方法は、予防です。自分のためにも、国家のため(=子供のため)にもなります。

 太陽の不活性化して急な氷河期を迎える可能性もあるそうですが、地球温暖化問題は深刻な問題であると思います。その二酸化炭素排出量の削減にもなると思います。

 そして、身体を鍛えるとバランスが良くなります。運動する事により、より集中力が高まります。

 次回は、自転車について書きます。

巡回セールスマン問題を解く(8)

 前バージョンの遺伝的アルゴリズム(GA)と今のバージョンを対決させてみた。今のバージョンには、局所解から脱出する力は皆無だけども、GAの方には局所解から脱出する力がある。試しに、今のバージョンで同じ問題を何回か解かせてみると、当然ながら成績が異なる。ちなみに、GAが局所解から脱出する力を発揮するためには、もの凄い時間が必要だ。両方の良い所をうまくミックスさせれば、もっと良くなるような気がしてきた。

追記:よくよく観察してみると、今のバージョンの中に改善を考慮すべき漏れがあった。これは、インプリメントしなければ…。

2009年6月12日金曜日

メルサバとんだ(2)

 いやー、CygWin の Mail::SPF::Query が test にパスしない。これは、痛い。と、トライ&エラーの連続で全然メルサバの復旧が進まん…。ひらめいた・・・飛んでイスタンブール・・・なんて書くから、飛んでメ~ルサ~バ~~~、復旧は、一向に進まない~~。そして、誰もいな~い~。放置プレーして帰ったろか~~。
 いっその事、cygwin フォルダごと上書きコピーしたろか・・・。とりあえず、そうしてみよっ。

メルサバとんだ

 あー、メールサーバのマシンが半分逝ってしまいました。長時間稼働すると、電源が切れる・・・。電源を冷やすファンだけが虚しく回っております。そんな、こんなで、本日もサーバ室からお届けしております。
 実は DRBD のスレーブマシンをまだ作成しておりません・・・。いや、500Gのディスクを他に流用していてですね・・・ごにょごにょ・・・なんです。ま、最近のディスクは SATA のケーブルでないと継らないんですが、スレーブマシンに使おうと思っていたパソコン、古すぎて IDE のケーブルしか付かない事が判明しました。ま、判明したのは、メールサーバのマシンがお亡くなりになって、緊急に検討したからなんですけどね・・・。これを機にメルサバもLinuxにしようか?と計画していたのが、ご破算です。
 前回の記事の続きです。結果を気にしている人は少数派かな? 
START TRANSACTION READ UNCOMMITED;
と明示的に指定するようにしてみました。ちなみに、START TRANSACTION READ COMMITED; も試しています。トランザクションは指定した方が速いです。しかし、劇的に速くはなりませんでした。どこがボトルネックか、プロファイリングでもとってみようと思っていますが、どこまでオレの仕事やねん。と、一人ボケツッコミしてます。
 近々の「ひらめいた」に考察と、「cmake で swig と php5 (2)」にCentOS編 追記しました。

2009年6月11日木曜日

Session と Transaction

 今日、100都市の巡回セールスマン問題デモの挙動を見ていて、はたと気が付きました。
 事前に300都市の全ての組み合わせの経路とコストを計算してあるので、300都市分の経路データをDBから読み込む時間は、都市数に関係なく定数時間で済みます。また、巡回セールスマン問題を解くルーチンは、100都市ならば1秒もかからずに計算できるはずなので定数時間と言って差し支えない。にもかかわらず、10都市で計算させる場合と、30都市で計算させる場合に明らかに時間が3倍ほど違ってきます。
 ウェブ・サービスの場合、HTTP/1.1 のプロトコルであろうと、セッションを持続する保障はどこにもありません。よって、リクエスト毎にミニマルな SQL 呼び出しを行い、大抵は BEGIN TRANSACTION から COMMIT を省略してしまいがちです。ところが、巡回セールスマン問題を解くルーチンでは、結果をデータベースに一旦保存しているので、1回のストアド・プロシジャ呼び出しに対して、都市数だけ更新が隠れています。TRANSACTION を指定しない場合は、オート・コミット・モードであり、都市数回の COMMIT が実行されているのではないか?って事です。
 ストアド・プロシジャ内で更新をかける場合には、IN TRANSACTION かどうかを調べて、TRANSACTION 外であれば、BEGIN TRANS から COMMIT でサンドイッチするように書いた方が良いのかもしれません。

本日のやっちまったい

 plpgsql の ostringstream や string が怪しいと思っていた部分は、関係ありませんでした。トホホ。でも、PostgreSQLの palloc を完全に利用するようにしたという意味では大きいです。

 ま、自信過剰でした。 Debug モードでビルドしていれば、BOOST_ASSERT のコンディションに引っかかって即決していたようなバグでした。こういう事前条件でいこうと設計していたのに、事前条件を破るような使いかたをしていたという、情けない話です。うーん・・・確実に記憶力は落ちてるな・・・こりゃ・・・orz

今朝、何気なく寂れた店を見てひらめいた

 今日は、あいにくの雨。そんな中、さびれた店の「バクダット」という文字を見て閃いた。ホロデッキのように、ドーム型の店内に、異国の景色を映し出すバー。ま、これは、莫大なコストがかかりそうなので、スーパーハイビジョンを擬似的な窓として、店内の窓は全て、スーパーハイビジョンに置き換えてしまうというもの。こんなバーがあったら、ちょっと行ってみたいかも?
 あー、本日は、飛んで「イスタンブール・デー」とか、ただいまから、ハワイ・タイムが始まりますとか・・・

追記:モニタを窓に見立てるのはいいけど、
  1. 席を移動しても景色が変わらない
  2. 窓に近づいても近景が得られない

という問題が考えられます。そうすると、モニタに移す景色は、遠景である方が良さそうです。複数の窓がある場合に、それらの相関関係を調整するのが至難の技のように思えてきました。3次元モニタなら、また違った展開になるのかな?とも思いましたが、解像度が 1/2 になってしまうのが難点です。そして、複数の窓の相関関係は、どうしようもありません。なかなか難しいもんですね・・・。

2009年6月10日水曜日

plpgsql の C関数きっついなー

 どうも、postgresql 用に書いた まとめて dijkstara する関数が、セグメンテーション・フォルトでお亡くなりになる。これの落ち方が、ヒステリックな感じで、よくわからない。まだ先は、わからないけど、std::ostringstream とか、std::string 系を使っている部分は、超怪しい気がしてきた…。で、sprintf に置き換えるとかしてるんだけど、boost::tokenizer とかも書き換えないといけまへん。10年以上振りに strtok の出番か?と、ゲンナリしてて(文字列領域をコピーして順番にatoiするだけなんだけど)、Cだけで文字列処理をやるのは、自虐的できっついですわ。

追伸、boost のレビュアが不足しているそうな…。レビューできるレベルの人は、多分、超絶に忙しい目に遭っているのでしょう。

CSS中のコメント

 デザインも基本パクリなんですが、pre タグ中の & が酷いな?と思っていたので、デザインをちょっとだけ修正しました。で、気がついてはいたんですが、IE で見ると width の扱いが異なっていて、がーーーーーんという部分も修正しました。

追記:後から見るとタイトルが変ですね。IE の CSS 中のコメント扱いは、おかしいというのを直した。って、事を書きたかったのだと思います。

2009年6月9日火曜日

本日はパンク

 本日もパンクと言った方がいいだろうか?数日前は、俺のストレス200%だったわけですが、今日は、データ絡みの原因不明のエラーと、ネットワーク管理と、Pマークでパンクしました。サーバ室の壁に頭を「ゴンゴン」ぶつけないとストレスでやっていけない。机の前でログを見ながら「あーーーーーーーっ」と声を出しっぱなしにしないとストレスでやっていけない。そんな状態でした。ウェブ・サーバは公開サイト兼、テスト・サイトと化しているので、公開サーバでデバッグをやるという、サーカス団なわけですが、SELinux の関係で、コンテキスト・ラベルが file_t になっている部分があるとかで、リラベルをかけて再起動したら、ファイル数が多すぎて全然終わらない…。まるでハングしているようで、いつ終わるとも知れないので、カーネルの起動オプションで、selinux=0 を付加して、fixfiles relabel しました。こっちの方が、まだいい。なんせ、ウェブ・サーバったら、DNSサーバも兼用しており、LANのWindowsサーバのDNSからのフォワード先にもなっているので、たまったもんじゃない…。フォワード先を変更して、ルータの設定を変更して…とかやってたら、マネジメントもくそもあったもんじゃない。パンクです。パンク。
 アーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーあぁぁああぁぁぁぁおあぁ

2009年6月8日月曜日

cmake で swig と php5 (2)

こちらの続きです。Ubuntu のタグがはってありますが、特に Ubuntu に特化した内容ではありません。
参考URLから、FindPHP5.cmake を生成します。テキストを切り出して php5.diff にしたと仮定
$ patch -p1 < php5.diff

こいつを、CMake の /share/CMake/Modules/ 下にコピーします。cmake のバージョンが上がると、標準のモジュールとして取り込まれているかもしれません。
CMakeLists.txt 中での使い方は
FIND_PACKAGE (PHP5)
######################################################
# Manual set for PHP5
######################################################
#SET (PHP5_INCLUDE_PATH "/usr/include/php5")
#SET (PHP5_EXECUTABLE "/usr/bin/php5")
IF (NOT PHP5FOUND)
MESSAGE ("---------------------------------------")
MESSAGE ("          !!! FATAL ERROR !!!          ")
MESSAGE ("---------------------------------------")
MESSAGE (FATAL_ERROR "PHP5 does not found.")
ENDIF (NOT PHP5FOUND)



FIND_PACKAGE (SWIG REQUIRED)

INCLUDE (${SWIG_USE_FILE})



SET (CMAKE_SWIG_FLAGS "")

SET_SOURCE_FILES_PROPERTIES (hoge.i PROPERTIES CPLUSPLUS ON)

SWIG_ADD_MODULE(hoge php5 hoge.i hoge.cpp fuga.cpp)



INCLUDE_DIRECTORIES (${PHP5_INCLUDE_DIR} ${PHP5_MAIN_INCLUDE_DIR}
${PHP5_TSRM_INCLUDE_DIR} ${PHP5_ZEND_INCLUDE_DIR} ${PHP5_REGEX_INCLUDE_DIR}
${PHP5_EXT_INCLUDE_DIR} ${PHP5_DATE_INCLUDE_DIR} ${PHP5_STANDARD_INCLUDE_DIR}
${INCLUDE_DIRECTORIES})





などとして、
$ cmake . -DCMAKE_BUILD_TYPE=Release

ビルドをすると、"hoge.php" と "hoge.so" が生成されます。
あとは、runme.php を
<?php
require "hoge.php";

$hoge = new fuga();
$hoge->bar();
?>

という感じで使えます。

ここからは、Ubuntu 固有かもしれません。
/etc/php5/conf.d/hoge.ini を
# configuration for hoge module
extension=hoge.so

としてやり、
/usr/lib/php5/20060613
の下に、hoge.so をコピーしました。なんかしらんけど、こんなんでコマンド・プロンプトからは動きました。

追記:CentOS 5.2 では、swig のバージョンが古くてコンパイルできません。rpmforge の swig は、輪をかけて古いです。という事で、本家からソースをダウンロードして
$ ./configure --prefix=/usr
$ make install

しました。
追記:CentOS 5.2 では、hoge.so を /usr/lib64/php/modules 下にコピーすればOKでした。i386 環境では、/usr/lib/php/modules だと推測されます。

windows service command

 本日も、ごちゃ混ぜな1日だった…。ネットワーク管理?マネジメント?デバッグ?Pマーク?
ネットワーク管理絡みで、windows の net start コマンドは、サービスの開始が完了するまで、net stop コマンドは、サービスの停止が完了するまで待ってはくれません。これでは、インストーラやバッチで利用するには不都合を感じる場合もあります。という事で、だいぶ前に書いたものを晒してみます。自由に使ってください。



#include <windows.h>
#include <iostream>
#include <boost/timer.hpp>
#include <boost/program_options.hpp>
#include <boost/iostreams/device/null.hpp>
#include <boost/iostreams/stream.hpp>

// null ostream
boost::iostreams::stream_buffer<boost::iostreams::null_sink> nsink;
std::ostream nstrm( &nsink );
// error ostream
std::ostream* estrm;

const char Desc[] = {
"Windows Service Control Program ver 0.1\n" \
"---------------------------------------\n" \
" net_service [ options ... ]\n" \
"sample: \n" \
" > net_service -n \"W3SVC\" --start --noerror --silent\n" \
" > net_service --name \"W3SVC\" --stop\n" \
"result: \n" \
" 0: success\n" \
" 1: invalid option\n" \
" 2: Can't open Service Control Manager\n" \
" 3: Can't open Service\n" \
" 4: Can't get Service Status\n" \
" 5: Can't start Service\n" \
" 6: Can't stop Service\n" \
" 7: Timeout error\n" \
"allowed options"
};

bool query_status( SC_HANDLE hSvc, DWORD& dwStatus ) {
SERVICE_STATUS status;
if( QueryServiceStatus( hSvc, &status) == FALSE) {
*estrm << "Can't get Service Status" << std::endl;
return false;
}
dwStatus = status.dwCurrentState;
return true;
}

void CloseHandles( SC_HANDLE& hSC, SC_HANDLE& hSvc ) {
if( hSvc ) CloseServiceHandle(hSvc);
if( hSC ) CloseServiceHandle(hSC);
hSvc = NULL;
hSC = NULL;
}

enum start_ctrl {
invalid_control = 0,
start_service,
stop_service
};

int main( int argc, char* argv[] ) {
bool noerror = false;
estrm = &std::cerr;
start_ctrl ctrl = invalid_control;
std::string service_name;
unsigned limits = 0;

try {
boost::program_options::options_description desc( Desc );
desc.add_options()
("help,h", "Procedure help message")
("name,n", boost::program_options::value<std::string>(), "Service Name. (required)")
("stop", "stop service")
("start", "start service")
("noerror", "always return 0. (=success)")
("silent,s", "silent mode: no report of errors and warnings")
("limits,t", boost::program_options::value<unsigned>(), "wait timeout sec. (default 0: forever)")
;

boost::program_options::variables_map vm;
boost::program_options::store(
boost::program_options::parse_command_line( argc, argv, desc ),
vm
);
boost::program_options::notify( vm );

if( vm.count("noerror") ) noerror = true;

if( vm.count("help") || argc <= 1 ) {
std::cout << desc << std::endl;
return (noerror) ? 0 : 1;
}

// invoke log option
if( vm.count("silent") ) {
nsink.open( boost::iostreams::null_sink() );
estrm = &nstrm;
}

if( vm.count("start") ) {
ctrl = start_service;
}
if( vm.count("stop") ) {
if( ctrl ) {
*estrm << "duplicate control options" << std::endl;
return (noerror) ? 0 : 1;
}
ctrl = stop_service;
}

if( vm.count("name") ) {
service_name = vm["name"].as<std::string>();
}

if( vm.count("limits") ) {
limits = vm["limits"].as<unsigned>();
}

SC_HANDLE hSC = OpenSCManager( NULL, NULL, GENERIC_EXECUTE);
if( hSC == NULL) {
*estrm << "Can't open Service Control Manager" << std::endl;
return (noerror) ? 0 : 2;
}

SC_HANDLE hSvc = OpenService(
hSC, service_name.c_str(), SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_STOP
);
if( hSvc == NULL) {
*estrm << "Can't open Service: \"" << service_name << "\"" << std::endl;
CloseHandles( hSC, hSvc );
return (noerror) ? 0 : 3;
}

DWORD dwStatus;
if( !query_status( hSvc, dwStatus ) ) {
CloseHandles( hSC, hSvc );
return (noerror) ? 0 : 4;
}

boost::timer t;

switch( ctrl ) {
case start_service: {
if( dwStatus != SERVICE_RUNNING ) {
if( StartService( hSvc, NULL, NULL) == FALSE) {
*estrm << "Can't start Service: \"" << service_name << "\"" << std::endl;
CloseHandles( hSC, hSvc );
return (noerror) ? 0 : 5;
}
while( query_status( hSvc, dwStatus ) ) {
Sleep( 250 );
std::cout << ".";
if( dwStatus == SERVICE_RUNNING) {
std::cout << std::endl << "\"" << service_name << "\" was started" << std::endl;
break;
}
if( limits && t.elapsed() >= limits ) {
*estrm << "Timeouts occured: " << t.elapsed() << " sec." << std::endl;
return (noerror) ? 0 : 7;
}
}
} else {
std::cout << "\"" << service_name << "\" is already started." << std::endl;
}
break;
}
case stop_service: {
if( dwStatus != SERVICE_STOPPED ) {
SERVICE_STATUS stat;
if( ControlService( hSvc, SERVICE_CONTROL_STOP, &stat) == FALSE) {
*estrm << "Can't stop service: \"" << service_name << "\"" << std::endl;
CloseHandles( hSC, hSvc );
return (noerror) ? 0 : 6;
}
while( query_status( hSvc, dwStatus ) ) {
Sleep( 250 );
std::cout << ".";
if( dwStatus == SERVICE_STOPPED) {
std::cout << std::endl << "\"" << service_name << "\" was stopped." << std::endl;
break;
}
if( limits && t.elapsed() >= limits ) {
*estrm << "Timeouts occured: " << t.elapsed() << " sec." << std::endl;
return (noerror) ? 0 : 7;
}
}
} else {
std::cout << "\"" << service_name << "\" is already stopped." << std::endl;
}
break;
}
default: {
*estrm << "no control options" << std::endl;
CloseHandles( hSC, hSvc );
return (noerror) ? 0 : 1;
}
}
CloseHandles( hSC, hSvc );
return 0;

} catch( std::exception& e ) {
*estrm << "error: " << e.what() << std::endl;
} catch( ... ) {
*estrm << "unknown error" << std::endl;
}

return (noerror) ? 0 : 1;
}

2009年6月7日日曜日

でもって、いろいろ

 教育大といい、農水省といい、配慮、配慮って、何を考えてるんでしょうか?この国は、アカウンタビリティに欠けてるんですよね。自由には責任が伴うって事を教育した方がいいのではなかろうか?指導者が責任を伴っていないのだから、それは無理ってもんだろ。
 梅田さん発言の続き、皆、日本に何を期待してるんでしょうか?ウェブで Google のような企業が日本から排出される事としか思えないです。日本でデス・バレーを超えられるような資金って、そんな簡単に得られるのでしょうか?その点で、ニコニコの覚悟って凄くないですか?そもそも、ウェブって、もう次のステージに入っていると思うのです。Flicker だって、膨大に増え続ける画像を無料でストックし続けられるのか疑問に思うのです。Facebookはどうでしょう?MySpaceは?Twitterは?ビジネス的に成功しているかどうかは、これだけ資金を費やしても、まだこれからでしょう?何を寝言こいてんだって感じです。任天堂のWiiを忘れていないでしょうか?もまえの提案するサービスで、ガバガバ儲ける事のできるビジネス・モデルを提案してみろってんだ。それが本物なら、スピード無しに実行すれば、とっくに他が真似をしているはずだ。
 で、次世代ウェブ・サービスは、家電のネット・サービス化。家電の一部機能をネットへアウトソーシングするというもの。どうでしょうか?わかりにくいと思うので、もう少し書くと、イコライザー、録画予約、調理手順の転送など。これらが一般化すると、家電操作MLが流通するようになるとか…。
 「自転車通勤のすすめ」については、改めて、エントリーをおこす予定。
 

2009年6月5日金曜日

cmake で swig と php5

 さっそく、ubuntu 環境で巡回セールスマン問題を解くクラスを perl 版、php5 版で作成してみました。比較的あっさりと動きました。後で、cmake で swig & php5 な構築をするための手順を書こうと思います。

参考は、これ

boost::lexical_cast は・・・

 こいつは便利だぜ~!と思っていたのだが、実務(仕事)で使って、結構痛い目にあったので、それ以後は lexical_cast を使っていない。boost users ML でも話題に上っていたが、std::atoi 感覚で文字列から数値にコンバートをかけると予期せぬ結果を生む。std::atoi では、スペースをトリミングしなくても正しく数値を読み込んでくれるのであるが、boost::lexical_cast は、スペースが先頭に付随すると問答無用で、0に変換する。いや、この記述は正しくない。実務で lexical_cast を導入した時には、スペースが先頭に付随していても問題なく数値変換が行われていたのである。途中で挙動が変わり、それは iostream に依存するのである。安全性を考えた場合、積極的に lexical_cast を使う理由が見つからない。
 もうひとつ、iostream 系の入出力で残念に思う事が、tuple の入出力だ。区切り文字にスペースを利用する場合に、tuple の要素が空だと、もうグタグタになってしまうのである。tuple は使い手があるようにも思えるのだが、どうにも iostream との組み合わせが頂けないのである。

いろいろ

 ブログを書くのが、ちょっとダレてきている。自分の日本語のセンスは最低である。何故なのか考えてみた。結論は、短期記憶力が弱いからではないか?というもの。書いているそばから、書いている事を忘れているのだと思う。だから、文章がぐだぐだになる。よくそれでコーディングが出来るな?と自分でも思う。

 ちょこちょこと書こうかな?と思っていた事を思い出してみる。

 まず、これからの携帯端末について。飛躍的に通信費が安くならない限り、大容量メモリの少量化によりストック型へと移行するのではないか?という予測。

 次に小売業の未来に関して。キーワードは「サービス」で、サービス・サイエンスが重要な時代なのだ。例えば自転車のパーツは通販で買っても本当に自分の自転車に合うかどうかの確信が持てない場合がある。生鮮食品は長距離通販には、今のところ適さない。消費者に何をサービスするのか?という事だ。大量生産品よりも手作りの味噌など、希少価値のある品が復権しても良いのではないか?とも思う。

 次が、梅田さんのインタビュー。元から、あまり著者を評価していなかったので、まぁ、そんなもんだろうと思う。一時期の私のS/N比をあげるためのフィルタのひとつが Web2.0を語るやつは偽者。梅田さんの著書は、本人の実体験を語っているような気がしたので「ウェブ時代をゆく」と、まぁ読んでお得だろの「ウェブ時代5つの定理」の2冊、「私塾のすすめ」は齋藤先生の本として読んでいるのでカウントしない。私塾のすすめのコンセプトは、「日本を教育した人々」からあり、こちらの方がメッセージ性は高いと思う。もちろん「学問のすすめ」は、すばらしい。

 そして、Swigの経験が役に立ちそうだ。なんかあったらSwig化して、あとは丸投げでけるかも?少々 template が混じっても、誤魔化すノウハウも得ている事だし…。

 思い出した・・・BING は Blogger のスコアが低いです。いくら Google 絡みのコンテンツだからって、そりゃねーだろ?という部分が自分としては残念です。悪くはない。あと、Wave は、よくわかんねーです。言うほど凄いとも思えない。技術的に凄くても一般ユーザにわかりやすくないとブレイクスルーはしないと思う。

 自転車・・・自転車通勤が不況もあってブームらしい。この間、時速 35km ぐらいでもう一台が前という状態で走っていたら、深夜に車道を右側通行する対向自転車に出くわして、急ブレーキをかけるハメになった。対向車の人が「お前ら反対だぞ」と、アホな事をぬかすので「反対はお前だろ」とつっこもうとしたら、前を走っていた人がキレて叫んでしまった…。自転車ブームになったら、マナーがどうとかコウルサイ事態になりそうだ。その後、前を走っていた人は怒りにまかせて時速 40km ぐらいですっとんでいった。さすがに平地で 40km は出せません…歳を感じました…。

 最後、電子ペーパーに期待!見開き型で、曲げセンサが付いていて「ペラペラめくり」の術が使えるやつをキボンヌ。

2009年6月4日木曜日

CWindowImplBase へんてこりんな設計

今日は、以下の部分をデバッグしていて、devenv と os レベルでハングしまくりで死にそうになった。前回も、ひっかかったのだが再現性がなくて放置したところだ。


const _ATL_MSG* pOldMsg = pThis->m_pCurrentMsg;

pThis->m_pCurrentMsg = &msg;

// pass to the message map to process

LRESULT lRes;

BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);

// restore saved value for the current message

ATLASSERT(pThis->m_pCurrentMsg == &msg);


 よく見れば、変な実装である。イベント実行中に他のイベントが発生していないかをチェックしているという事であろうか?自分のクラスのインスタンスのメンバ変数にストックしておいて、値が変わっていない事を表明している。確かに・・・しかし、回りくどい。何故こんな事をしなければならないのか?それは、GetCurrentMessage() なる怪しげな関数があるからだ。なんというか、この設計は生理的に受け付け難いものを感じてしまう。しかし、このassertのおかげで、解決が速くなったので感謝すべきか?
 結局のところ、WM_PAINT によるメッセージ中に COM アウトゴーイング・インターフェイス=イベントを発生したハンドラから、再描画を促すコードが発行されているのが原因のようだった。しょうがないから、WM_PAINT を実行する部分をフラグによりロックアウトして対処した。擬似コードは以下。


HRESULT CFoo::OnPaint(HDC hDC) {
if( m_bPaintLockout ) return S_OK;
m_bPaintLockout = TRUE;
...
m_bPaintLockout = FALSE;
return S_OK;
}


追記:どう考えても変だ。Windowsはイベント・ドリブン型で、メッセージは基本シングル・プロセスで処理され、メッセージ・キューに溜まるだけのはずである。マルチスレッドにイベントを処理していなければ、このような事態に陥るはずがない。IOleInPlaceSiteWindowressImpl 絡みで、m_bWindowOnly = TRUE を設定しているだが、CWindowImplBaseT あたりの動きが不穏すぎて、よくわからない。ATLの設計はCRTPで、しかも変てこりんなので(CExeModuleとCServiceModuleの設計はひどかった)デバッグは勘弁してほしいところだ。
追記:こんだけ、くそみそに書いてて、結局、null アクセスしてただけだったよ…トホホ…。情けねぇ。

俺のストレスはマックス200%(devenv士ね)

 Visual Studio 2008 も状況は変わらない。インテリセンスいらね。devenv 士ね。
ひでぇーぞ、*.idb が削除できません。このフォルダは、違うプロセスにより…。おいーーーーーっ、devenv のプロセスは終了してるぜよーーーーっ。他に、このフォルダを掴む犯人は、もまえ以外にいない。
 今日も multi task manager の刑じゃーーーー。しょっぱなから、こけて、何も出けんのじゃーーーーーーーーーー。ストレス・マックス200%じゃーーーーーーっ。
devenv 士ね。

2009年6月3日水曜日

devenv hotfix 祭りじゃー

 今日もまた、Multi task manager になった。そして、やはり、devenv 。行き着く先は、ディスクチェック

 デバッグ、できないだろーーーーーっ。という事で、HOTFIX の リサーチ開始。sp2 まで待てません。
という事で、見つけたのがここ


 うぉーーーっ、祭りじゃ祭りじゃーーーーっ。

  わっしょい、わっしょい、わっしょい、わっしょい。

HOTFIX インスコ祭りじゃーーーっ

  わっしょい、わっしょい、わっしょい、わっしょい。
    わっしょい、わっしょい、わっしょい、わっしょい。
      わっしょい、わっしょい、わっしょい、わっしょい。
  わっしょい、わっしょい、わっしょい、わっしょい。
    わっしょい、わっしょい、わっしょい、わっしょい。
       わっしょい、わっしょい、わっしょい、わっしょい。
    わっしょい、わっしょい、わっしょい、わっしょい。
   わっしょい、わっしょい、わっしょい、わっしょい。
  わっしょい、わっしょい、わっしょい、わっしょい。
   わっしょい、わっしょい、わっしょい、わっしょい。

追記:どれひとつとして、インストールできない。sp2 まだ~?
追記:つか、sp2 じゃん orz... 。 sp3 まだ~?

2009年6月2日火曜日

商品を買った人だけに風船

 あー、あるある。息子に「風船を配ってるみたいだよ。貰っといで」と言ったら、恥ずかしがり屋の息子は、周りをオロオロとする。そのうち、どうも商品を買った人だけに風船を配っているという事に気がついて、「ああー、ごめんよ、何か買わないと風船はもらえないみたいだよ。残念だったねー」と、慰めるというシチュエーション。この辺は、性格によるところが大きいみたいです。ズバッと風船を下さいと言えない分、まぁ、いいか・・・と、そんなにダメージも無い。「風船をください」と言える方が行動力があっていいのではないか?とも思います。