Home

VSUG Day Summer 2012

2012-05-21 21:11:54

VSUG Day がまた開催されます。お申し込みは こちら から。Windows 8 & Visual Studio 2012 が目前に迫っているので、いろいろと楽しみです。うーん。時間があったら行きたいところですが、今のところ、ちょっとどうなるか不明...。

image/vsugday_s_2012.png

Go to TopGo to Top

oplock break

2012-05-12 19:21:59

きちんと解決できたわけじゃないけど、メモ代わりに。コトの発端は、クライアントからサーバー上のファイルにアクセスするときに、えらい遅くなるケースがある、という、よくありがちな話。

そういうときは、とりあえず WinDBG を使って、アプリケーションでどんな処理が行なわれているか確認すると。見てみると、ゴニョゴニョしてる結果として、最終的に ReadFile() 関数で一バイトごとにアクセスが行なわれているわけです。そりゃ遅いわ。

ただ、どうにもそれだけの問題じゃないようで、パケットを見てみると、サーバーからの oplock break を受信した後にそういう動作になると。SMB については全然知らないので、この辺 だとかを見ながらいろいろ試したんですが、結局、設定では何ともならなそう、という結論に。アプリケーションを修正して、読み込み方法を変えれば『遅くなる』って事象も回避できたので、とりあえずはそんな感じで。

なんつーか、もやもやした感じは残りつつも、オペレーティングシステムの不具合(?) をアプリケーションで回避するのはいつものこと、ということで自分を納得させました。

Go to TopGo to Top

in_addr

2012-05-08 22:48:21

ちょっとメモ。こういうときに共用体って便利だなぁって思いますよね。


  #include "stdafx.h"
  #include <WinSock2.h>

  int _tmain(int argc, _TCHAR* argv[])
  {
    in_addr ia1;
    in_addr ia2;

    ia1.S_un.S_un_b.s_b1 = 192;
    ia1.S_un.S_un_b.s_b2 = 168;
    ia1.S_un.S_un_b.s_b3 = 0;
    ia1.S_un.S_un_b.s_b4 = 1;

    // 16820416
    printf("%d\n", ia1.S_un.S_addr);
    ia2.S_un.S_addr = ia1.S_un.S_addr;

    // 192.168.0.1
    printf("%d.%d.%d.%d\n",
      ia2.S_un.S_un_b.s_b1,
      ia2.S_un.S_un_b.s_b2,
      ia2.S_un.S_un_b.s_b3,
      ia2.S_un.S_un_b.s_b4);

    return 0;
  }

Go to TopGo to Top

ちょっとだけ iPhone 対応

2012-05-05 11:11:06

iPhone 対応といっても、viewport を指定したのと、css をちょっとだけ修正したくらいですが、それでも見た目的には "それなり" になるもんなんですね。


ちょっと追記。

漏れがあったので、ちょこちょこ修正。過去にさかのぼるのはアレなので、今年分くらいでいいですかね。

Go to TopGo to Top

プロセス数の制限

2012-05-03 15:58:18

Linux / UNIX では、ユーザーごとの最大プロセス数とかが制限できたりしますが、Windows ではそういう設定はありません。ということで、親プロセス側で管理したり、ってのが一般的な方法になっちゃいますが、Job Object を利用した方法を試してみました。

やり方は簡単で、JOBOBJECT_BASIC_LIMIT_INFORMATION 構造体の ActiveProcessLimit メンバに Job 内のアクティブプロセスの数を指定するだけ。『アクティブプロセス』ってことで、Suspended なプロセスはどうなるの? とかって思わなくもないですが、気にしないでおきます。

例のごとく、Explorer から起動するとうまく動かないので注意が必要と。[ ファイル名を指定して実行 ] からコマンドプロンプトを立ち上げて、その中で実行すればうまく行きます。

で、自分を入れて 5 つプロセスが立ち上がっていると、それ以上は ERROR_NOT_ENOUGH_QUOTA エラーが発生して起動できなくなる、と。使いどころは...。微妙ですね。



  #include "stdafx.h"
  #include <windows.h>

  int _tmain(int argc, _TCHAR* argv[])
  {
    HANDLE hJob;
    JOBOBJECT_BASIC_LIMIT_INFORMATION jbli;
    BOOL result;
    DWORD err;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
  
    hJob = ::CreateJobObject(NULL, _T("MyJob"));
    if (!hJob) {
      _tprintf(_T("Error CreateJobObject() : 0x%x\n"),
               ::GetLastError());
      goto fin;
    }
    ::ZeroMemory(
        &jbli,
        sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION));
    jbli.LimitFlags = JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
    jbli.ActiveProcessLimit = 5;
    result =
      ::SetInformationJobObject(
          hJob,
          JobObjectBasicLimitInformation,
          &jbli,
         sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION));
    if (!result) {
      _tprintf(_T("Error SetInformationJobObject() : 0x%x\n"),
               ::GetLastError());
      goto fin;
    }

    result =
      ::AssignProcessToJobObject(
          hJob,
          ::GetCurrentProcess());
    if (!result) {
      _tprintf(_T("Error AssignProcessToJobObject() : 0x%x\n"),
               ::GetLastError());
      goto fin;
    } else {
      _tprintf(_T("Success AssignProcessToJobObject() Function.\n"));
    }

    for (int i = 0; i < 10; i++) {

      _tprintf(_T("Hit any key to create new process #%d\n"),
               i + 1);
      getchar();

      ::ZeroMemory(&si, sizeof(STARTUPINFO));
      ::ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
      si.cb = sizeof(STARTUPINFO);
      result =
        ::CreateProcess(
            _T("C:\\Windows\\notepad.exe"), 
            NULL, NULL, NULL, FALSE, 0,
            NULL, NULL, &si, &pi);
      if (!result) {
        err = ::GetLastError();
        if (err == ERROR_NOT_ENOUGH_QUOTA) {
          _tprintf(_T("Process limit exceeded.\n"));
        } else {
          _tprintf(_T("Error CreateProcess() : 0x%x\n"), err);
        }
      }

      ::CloseHandle(pi.hThread);
      ::CloseHandle(pi.hProcess);
    }

  fin:
    ::CloseHandle(hJob);
    return 0;
  }


Go to TopGo to Top