2011/07/14


GoogleのGo 節電 プロジェクトが全然Go言語に関係なくて悲しかったので、本日公開されたGo節電プロジェクトAPIを叩くインタフェースライブラリを書いた。
mattn/go-setsuden - GitHub

interface to gosetsuden API.

https://github.com/mattn/go-setsuden
使い方はexampleフォルダにある物を参照下さい。
package main

import "github.com/mattn/go-setsuden"

func main() {
    println("■東京の最新計測値")
    pu, _ := setsuden.GetActualUsage("tokyo")
    for _, p := range pu {
        println("時間", p.Datetime)
        println("間隔", p.Duration)
        println("値 ", p.Value)
    }
    println()

    println("■東京の最新予測値")
    pu, _ = setsuden.GetEstimatedUsage("tokyo")
    for _, p := range pu {
        println("時間", p.Datetime)
        println("間隔", p.Duration)
        println("値 ", p.Value)
    }
    println()

    println("■東京の最新瞬時値")
    pu, _ = setsuden.GetInstantUsage("tokyo")
    for _, p := range pu {
        println("時間", p.Datetime)
        println("間隔", p.Duration)
        println("値 ", p.Value)
    }
    println()

    println("■東京の電力供給ピーク値")
    pp, _ := setsuden.GetPeakOfSupply("tokyo")
    for _, p := range pp {
        println("開始", p.Start)
        println("終了", p.End)
        println("値 ", p.Value)
    }
    println()

    println("■東京の電力供給ピーク予想値")
    pp, _ = setsuden.GetPeakOfDemand("tokyo")
    for _, p := range pp {
        println("開始", p.Start)
        println("終了", p.End)
        println("値 ", p.Value)
    }
    println()
}
さっき実行したらこんな感じでした。
■東京の最新計測値
時間 2011-07-14T10:00:00+09:00
間隔 3600
値  43480000

■東京の最新予測値
時間 2011-07-14T19:00:00+09:00
間隔 3600
値  41580000

■東京の最新瞬時値
時間 2011-07-14T11:25:00+09:00
間隔 300
値  44360000

■東京の電力供給ピーク値
開始 2011-07-14T09:00:00+09:00
終了 2011-07-14T20:00:00+09:00
値  52700000

■東京の電力供給ピーク予想値
開始 2011-07-14T14:00:00+09:00
終了 2011-07-14T15:00:00+09:00
値  45500000

Go言語、全然関係無いですね!
Posted at by



2011/06/30


javascript:for (var b=document.getElementsByTagName("*"), n = 0; n < b.length; n++) { if (b[n].getAttribute("g:type") == "plusone" && b[n].getAttribute("aria-pressed") != "true") b[n].click() }
Posted at by



2011/06/28


ダウンロード配布物となっている mingw の c++config.h では /* Define if gthreads library is available. */
/* #undef _GLIBCXX_HAS_GTHREADS */
となっていて、下記の様なthreadを使ったコードはコンパイル出来ないのですが #include <atomic>
#include <thread>
#include <iostream>

std::mutex m ;
int x ; 

void thread()
{
    std::lock_guard<std::mutex> guard(m) ;
    ++x ; // 非アトミック操作
}

int main()
{
    x = 0 ; // 初期値0

    std::thread A( thread ) ;
    std::thread B( thread ) ;

    A.join() ; B.join() ;

    std::cout << x << std::endl ; // 2であるべき
}
本の虫: C++0xのマルチスレッドとデータ競合が非常に難しい

「バリアー!」「デュクシ!」「ちょっ、お前、オレ、バリアー張...

http://cpplover.blogspot.com/2011/06/c0x.html
手を加えてやる事でビルド出来る事が分かった。まずはオプションを上書きしてやる。 #define _GLIBCXX_HAS_GTHREADS 1
#define _GLIBCXX__PTHREADS 1
#define _POSIX_TIMEOUTS 1
次に、gthreadsが内部処理の為に定義しているスレッド識別子による比較関数を定義する #include <pthread.h>
inline bool
operator<(const pthread_t& lhs, const pthread_t& rhs) { 
  return lhs < rhs;
}
この状態でとりあえずコンパイルは出来る。ただしgthreads無効でビルドされているのでスレッド操作関数の実体が無い。そこでthread.ccからコードを拝借する。 namespace std
{
  namespace
  {
    extern "C" void*
    execute_native_thread_routine(void* __p)
    {
      thread::_Impl_base* __t = static_cast<thread::_Impl_base*>(__p);
      thread::__shared_base_type __local;
      __local.swap(__t->_M_this_ptr);

      __try
        {
          __t->_M_run();
        }
      __catch(...)
        {
          std::terminate();
        }

      return 0;
    }
  }
  void
  thread::_M_start_thread(__shared_base_type __b)
  {
    if (!__gthread_active_p())
      __throw_system_error(int(errc::operation_not_permitted));

    __b->_M_this_ptr = __b;
    int __e = __gthread_create(&_M_id._M_thread,
                               &execute_native_thread_routine, __b.get());
    if (__e)
    {
      __b->_M_this_ptr.reset();
      __throw_system_error(__e);
    }
  }
  void
  thread::join()
  {
    int __e = EINVAL;

    if (_M_id != id())
      __e = __gthread_join(_M_id._M_thread, 0);

    if (__e)
      __throw_system_error(__e);

    _M_id = id();
  }
}
全体のソースだとこんな感じ。 // {{{
// vi:set ts=8 sts=2 sw=2 tw=0:
// vim:fdm=marker fdl=0 fdc=0 fdo+=jump,search:
// vim:fdt=substitute(getline(v\:foldstart),'\\(.\*\\){\\{3}','\\1',''):
#define _GLIBCXX_HAS_GTHREADS 1
#define _GLIBCXX__PTHREADS 1
#define _POSIX_TIMEOUTS 1
#include <pthread.h>
inline bool
operator<(const pthread_t& lhs, const pthread_t& rhs) { 
  return lhs < rhs;
}
// }}}

#include <atomic>
#include <thread>
#include <iostream>

// {{{
namespace std
{
  namespace
  {
    extern "C" void*
    execute_native_thread_routine(void* __p)
    {
      thread::_Impl_base* __t = static_cast<thread::_Impl_base*>(__p);
      thread::__shared_base_type __local;
      __local.swap(__t->_M_this_ptr);

      __try
        {
          __t->_M_run();
        }
      __catch(...)
        {
          std::terminate();
        }

      return 0;
    }
  }
  void
  thread::_M_start_thread(__shared_base_type __b)
  {
    if (!__gthread_active_p())
      __throw_system_error(int(errc::operation_not_permitted));

    __b->_M_this_ptr = __b;
    int __e = __gthread_create(&_M_id._M_thread,
                               &execute_native_thread_routine, __b.get());
    if (__e)
    {
      __b->_M_this_ptr.reset();
      __throw_system_error(__e);
    }
  }
  void
  thread::join()
  {
    int __e = EINVAL;

    if (_M_id != id())
      __e = __gthread_join(_M_id._M_thread, 0);

    if (__e)
      __throw_system_error(__e);

    _M_id = id();
  }
}
// }}}

std::mutex m ;
int x ; 

void thread()
{
    std::lock_guard<std::mutex> guard(m) ;
    ++x ; // 非アトミック操作
}

int main()
{
    x = 0 ; // 初期値0

    std::thread A( thread ) ;
    std::thread B( thread ) ;

    A.join() ; B.join() ;

    std::cout << x << std::endl ; // 2であるべき
}
これ、vimmerならfoldを使ってやれば //                                                                               

#include <atomic>
#include <thread>
#include <iostream>

//                                                                               

int main() {
  std::mutex m;
  int x = 0;

  std::thread A([&] {
    for (int n = 0; n < 100; n++)  {
      std::lock_guard<std::mutex> guard(m);
      ++x;
      std::cout << x << std::endl;
    }
  });
  std::thread B([&] {
    for (int n = 0; n < 100; n++)  {
      std::lock_guard<std::mutex> guard(m);
      ++x;
      std::cout << x << std::endl;
    }
  });

  A.join();
  B.join();
}

こんな風に見えてちょっとはマシになる。これでmingw使ってthreadなプログラミングが出来ますね!
lambda使えばこんなのも出来て、たのしーーーー!

#include <atomic>
#include <thread>
#include <iostream>

int main() {
  std::mutex m;
  int x = 0;

  std::thread A([&] {
    for (int n = 0; n < 100; n++)  {
      std::lock_guard<std::mutex> guard(m);
      ++x;
      std::cout << x << std::endl;
    }
  });
  std::thread B([&] {
    for (int n = 0; n < 100; n++)  {
      std::lock_guard<std::mutex> guard(m);
      ++x;
      std::cout << x << std::endl;
    }
  });

  A.join();
  B.join();
}

Posted at by