[リストへもどる]
一括表示
タイトルCPXについての質問2件
記事No15
投稿日: 2005/11/12(Sat) 15:40
投稿者YOS   <cra-top.yoshida@nifty.com>
Q.1 画像は、ローカルに保存されますか?
Q.2 シングルスレッド指定って、複数の巡回フォルダに共通して、有効ですか?

【補足】

Q.1 画像は、ローカルに保存されますか?

本文内にimgタグがある場合、ローカルに保存されて、オフライン状態でも閲覧可能と言うことでしょうか?
てっきり、imgタグの場合、常に、inet上の画像ファイルを参照するとばかり思っていました。
指摘されて気が付きました。
こういう認識で良いでしょうか?

Q.2 シングルスレッド指定って、複数の巡回フォルダに共通して、有効ですか?

cpxGetExtInfoProp(var ExtInfoProp: TExtInfoProp); stdcall;

ExtInfoProp.bSingleThread := True;// シングルスレッドモード

と、設定されていることから、複数の巡回フォルダに、同じCPXを設定した場合、共通して、シングルスレッド動作するんですよね?
同じCPX(シングルスレッドモード設定)を使う、フォルダA、B、Cの3つがあった場合、

1.Aを巡回。その間は、B、Cは、待っている。
2.Bを巡回。その間は、Cは、待っている。
3.Cを巡回。

こういう動作をしますか?順番はともかくも。

----
YOS cra-top.yoshida@nifty.com by CMN 0.50β + YosPad 1.34
http://com.nifty.com/community/C0023097/top.go

タイトルRe: CPXについての質問2件
記事No16
投稿日: 2005/11/12(Sat) 21:42
投稿者うぇいく   <weyk@nifty.com>
 こんにちは。
>Q.2 シングルスレッド指定って、複数の巡回フォルダに共通して、有効ですか?

>cpxGetExtInfoProp(var ExtInfoProp: TExtInfoProp); stdcall;

>ExtInfoProp.bSingleThread := True;// シングルスレッドモード

>と、設定されていることから、複数の巡回フォルダに、同じCPXを設定した場合、共通して、シングルスレッド動作するんですよね?
Mixi_Diaryで試す限り、見た感じしてませんね。説明自体も、
「bSingleThread フォルダ内の掲示板をシングルスレッドで巡回する場合は TRUE、それ以外は FALSE。」
とあるので、フォルダ内に閉じて、シングルスレッドであることを保障するのでしょう。
# フォルダ内の掲示板を ですから。

 当方では、同時に実行したくないところのみ、InitializeCriticalSection/EnterCriticalSection/LeaveCriticalSectionにて、制御してます。
# これは、Win32API。VCLにも似たものがあるかどうかは不明。
# ただし、当方での利用は、1インスタンスの複数スレッドの禁止のみ。全てのインスタンスで禁止するには、CRITICAL_SECTIONの変数をstaticで宣言した上で、最初の1度のみInitializeする必要がある・・・と思う=^^;=/でも、初期化よりも、Deleteするタイミングの方が難しいかも・・・cpxPilotStartとcpxPilotEndでも良いのかな?
ただ、自力で実装した場合、DeadLockの心配も自分でしないといけなくなっちゃうんですよね・・・
-- CMN v0.50β --

タイトルRe2: CPXについての質問2件
記事No17
投稿日: 2005/11/13(Sun) 14:06
投稿者YOS   <cra-top.yoshida@nifty.com>
#16 うぇいくさん、こんにちは。

># フォルダ内の掲示板を ですから。

うっ、仕様書の存在を、忘れてました。

>ただ、自力で実装した場合、DeadLockの心配も自分でしないといけなくなっちゃうんですよね・・・

そうなっちゃいますよね。
複数フォルダに、同じCPXを設定した場合、別インスタンスになるでしょうから、排他処理を考えないといけませんね。

厳密に言うと、ログインの要・不要も、テキストファイル形式で書き込んでいますから、これも、同時書き込み要求をした場合の排他処理をしないといけませんね。
Winでは、フォルダを作成するのが、一番お手軽みたいですが。

200も入れられるんだから、一つのフォルダにして欲しいものです。

----
YOS cra-top.yoshida@nifty.com by CMN 0.50β + YosPad 1.34
http://com.nifty.com/community/C0023097/top.go

タイトルRe3: CPXについての質問2件
記事No18
投稿日: 2005/11/14(Mon) 09:49
投稿者うぇいく
>200も入れられるんだから、一つのフォルダにして欲しいものです。
 えー、現在、コミュニティ1つ、受信簿、送信簿の3つアイテムを巡回していますが、巡回フォルダは2つです(笑)コミュニティで1つ、メッセージで1つ。いちおー、巡回パターンで、巡回順序を離すことで利用しています。
# さらにほかの種別の巡回を行う場合、たぶんまたフォルダを分割します。ただ、受信waitがある関係で、他の巡回よりも時間がかかるので、結構間に挟んでおかないとタイミングが重なっちゃいますね。

 あとフォルダでの、「通常フォルダでの」右クリック→既読や、タイトルビューでの「ツリーを既読」は、新しいユーザが増えるごとに毎回出てくると思います。必要になるのは、最初に巡回したときですから。
# その時点で、ショートカットキーによる操作を見つけているとも限らないし、そもそも右クリックから「全て選択」「属性変更→既読にする」を行えるとも思えないし・・・

 ちなみに。私の感覚では、1つのフォルダ(巡回対象の種類)とかで、2〜3百の未読がある場合(会社で巡回・チェック済みの分を、家で取得した とか。OTNJPの2〜3日分)でも、スペースキーを押しっぱなしにします。現時点で22個の掲示板になりますが、それぞれで開いて全て選択して既読にする(22回・・というか実際に未読があるのは5〜8掲示板ぐらい)よりも楽です(時間はかかるかもしれませんが。)

 さらにちなみに。cpxからでは受信済みのログにアクセスできないため、「既読で取り込む」ことはできますが、「受信済みを既読にする」ことはできません(初期巡回のオプションとして、「全て既読で取り込む」は有効かもしれません。)
 また、右クリックからのメニューに項目を追加した場合、巡回時に合わせて、各発言が呼び出されるようになります(送信前・・・でしたっけ?)これを利用して、TMesの内容からそっくり同じ発言を受信したかのように見せかけて既読にすることはできそうですが、チェックした発言しか渡ってこないため、「ツリーで」というのはたぶん無理です。
# いまのところ、メニューの拡張はOTN-JPでしか使ってません・・・「削除予約」とかつけてます。niftybbsも削除予約つけよう・・・・と思ったら画面遷移が無駄に複雑でした・・・できれば、ブラウザ開かずに管理したい(管理者削除も含めて。spam多いし。)ところです。
-- CMN v0.50β --

タイトルRe4: CPXについての質問2件
記事No20
投稿日: 2005/11/14(Mon) 16:02
投稿者YOS   <cra-top.yoshida@nifty.com>
#18 うぇいくさん、こんにちは。

># さらにほかの種別の巡回を行う場合、たぶんまたフォルダを分割します。
うーむ。(^_^;
ただ、いずれ出てくる操作なので、考えないといけませんね。

>ただ、受信waitがある関係で、他の巡回よりも時間がかかるので、結構間に挟んでおかないとタイミングが重なっちゃいますね。

とりあえず、これしかないですね。
あとは、その度ごとに、mixiだけ手動で、巡回させるとか。

排他処理は、

・排他処理を行いたいCPXが、一定の書式(Lock.エクステンション名など)でフォルダを作成し、巡回開始。
終了後、ロックフォルダを削除。
・次に起動したCPXは、フォルダがあるうちは、待つ。

で、不正終了時にロックフォルダが残ってしまった対策として、

・CMNが、起動時に、ロックフォルダの有無を確認し、あれば、全削除。

やるとしたら、こんな仕組みでしょうか?
これだと、sdk拡張しないで済みますよね。

以前、ファイルの二重起動防止で、排他処理を実装したことがあります。
その際には、日付の変わっているロックフォルダがあったら削除と言うことにしました。
でも、これを、CPXで行う訳にはいきませんよね。
手動で削除しない限り、その日は、巡回不可になりますから。

> さらにちなみに。cpxからでは受信済みのログにアクセスできないため、「既読で取り込む」ことはできますが、「受信済みを既読にする」ことはできません(初期巡回のオプションとして、「全て既読で取り込む」は有効かもしれません。)

この辺は、今朝、書きました。
親発言の更新については、何とかなるのかも知れませんが、子発言が、コメント先として、元の番号を指定していますから、どっちにしても、ツリーが崩れますので、同じ事ですね。

># いまのところ、メニューの拡張はOTN-JPでしか使ってません

私は、ご存じのように、一切未対応ですね。
「それどころじゃない」のが、本当の理由です。
通常の巡回だけで、手一杯ですから。(^^;ゞポリポリ

----
YOS cra-top.yoshida@nifty.com by CMN 0.50β + YosPad 1.34
http://com.nifty.com/community/C0023097/top.go

タイトルRe: CPXについての質問2件
記事No21
投稿日: 2005/11/14(Mon) 18:59
投稿者DECO
YOSさん、こんにちは。

>Q.1 画像は、ローカルに保存されますか?

IMGタグやBODY等に指定されたbackgroundは基本的に受信してローカルに保存されます。
スクリプトで画像を表示している場合は受信できない場合があります。

>Q.2 シングルスレッド指定って、複数の巡回フォルダに共通して、有効ですか?

CPSのSINGLETHREADと同じ機能でして、フォルダ内の掲示板を順次巡回する機能なので、フォルダ間の排他制御はしません。

以上、遅くなりましたが。

DECO

タイトルRe2: CPXについての質問2件
記事No23
投稿日: 2005/11/15(Tue) 11:54
投稿者YOS   <cra-top.yoshida@nifty.com>
#21 DECOさん、こんにちは。

>IMGタグやBODY等に指定されたbackgroundは基本的に受信してローカルに保存されます。
>スクリプトで画像を表示している場合は受信できない場合があります。

分かりました。
可能性としては、保存できない場合もあるんですね。
ただ、mixiの場合は、保存できたようで、OKみたいです。

>CPSのSINGLETHREADと同じ機能でして、フォルダ内の掲示板を順次巡回する機能なので、フォルダ間の排他制御はしません。

やはり、そうでしたか。
ふと考えたんですが、CPXごとに、複数フォルダがあっても、必ず最初に実行させる手続きがあるんですから、ここでロックフォルダの事前クリアを行っておけば、デッドロック(っていうのかな?)は起きないような気がしてきました。

特に問題なければ、この線で、複数フォルダ間の排他処理を検討してみます。

----
YOS cra-top.yoshida@nifty.com by CMN 0.50β + YosPad 1.34
http://com.nifty.com/community/C0023097/top.go

タイトルRe3: CPXについての質問2件
記事No24
投稿日: 2005/11/15(Tue) 12:43
投稿者うぇいく
 ロックについてはたぶん、DLLのロード時点とアンロード時点で、
TCriticalSection
を利用するほうが確実です。
# TCriticalSectionのインスタンスを生成・破棄するタイミングに注意。

# どっちにしろ、多重で動作できるはずのアクティブな巡回スレッドをとめてしまうことになるので、cpx側で長時間の排他が必要になるのは、ちょっと困りものです。「アクティブスレッドの差し戻し」ができても面白いかも(スレッドの振り分けを最後尾に回す。他の全てのスレッドが1度以上差し戻しを行った場合はなんらかの通知をする(最後尾競争にならないため))
-- CMN v0.50β --

タイトルRe4: CPXについての質問2件
記事No25
投稿日: 2005/11/15(Tue) 15:28
投稿者YOS   <cra-top.yoshida@nifty.com>
#24 うぇいくさん、こんにちは。

> ロックについてはたぶん、DLLのロード時点とアンロード時点で、
>TCriticalSection
>を利用するほうが確実です。

なるほど。
となると、本体の機能ですね。

>他の全てのスレッドが1度以上差し戻しを行った場合はなんらかの通知をする(最後尾競争にならないため))

mixiの場合、これが、頻繁に起きそうです。(^_^;

----
YOS cra-top.yoshida@nifty.com by CMN 0.50β + YosPad 1.34
http://com.nifty.com/community/C0023097/top.go

タイトルRe5: CPXについての質問2件
記事No33
投稿日: 2005/11/21(Mon) 11:22
投稿者うぇいく
Delphiのcpx側でやるとすると、こうかな・・・

1.usesに以下のユニットを追加。
  SyncObjs

2.ユニット変数を宣言
var
  CritSec:TCriticalSection;

3.ユニット関数(?)を宣言
procedure LibraryProc(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH: begin
      CritSec:=nil;
      CritSec:=TCriticalSection.Create;
      end;
    DLL_PROCESS_DETACH: begin
      if CritSec <> nil then
        CritSec.Free;
        CritSec:=nil;
      end;
  end;
end;

4.初期化処理(ユニットの手続き)を追加
  DllProc := @LibraryProc;
  LibraryProc(DLL_PROCESS_ATTACH);

5.フォルダ開始時にロックを確保を追加
  Result := True;
  if CritSec = nil then begin
    pICmnPilot.cmnStatus ('フォルダロックエラー',TRUE);
    Result := False;
  end else begin
    pICmnPilot.cmnStatus ('フォルダロック獲得待ち・・・',FALSE);
    CritSec.Enter;
  end;

6.フォルダ終了時にロックを開放を追加
  CritSec.Leave;


うーむ、Delphiはどーにもよく判らない・・・
-- CMN v0.50β --

タイトルRe6: CPXについての質問2件
記事No34
投稿日: 2005/11/21(Mon) 15:43
投稿者YOS   <cra-top.yoshida@nifty.com>
#33 うぇいくさん、こんにちは。

>Delphiのcpx側でやるとすると、こうかな・・・

良い機会なので、超基本的なことかも知れませんが、教えてください。

>2.ユニット変数を宣言
>var
> CritSec:TCriticalSection;

これは、スタティックに確保していると言うことですね。
で、同一CPX、つまり、各巡回フォルダを巡回するCPXから、共通して参照されると言うことで。

>4.初期化処理(ユニットの手続き)を追加
> DllProc := @LibraryProc;
> LibraryProc(DLL_PROCESS_ATTACH);

このように、DLLの関数呼び出しみたくアドレスを割り当てるのは?
これは、cpxFolderPilotStartあたりに書いておくのかな?
えーと、cpxPilotStartかな?

>5.フォルダ開始時にロックを確保を追加
> Result := True;
> if CritSec = nil then begin
> pICmnPilot.cmnStatus ('フォルダロックエラー',TRUE);
> Result := False;
> end else begin
> pICmnPilot.cmnStatus ('フォルダロック獲得待ち・・・',FALSE);
> CritSec.Enter;
> end;

あれ?CritSec.Enterが、ここにしかないですね。
つまり、CriticalSectionに入って何かするのではなく、CriticalSectionには入れたかどうかで、判定すると言うことかな?

この場合、ほぼ同時に要求する場合、どうなるんだろう?

えーと、以上から、想像を書きます。

【宣言部】

type
  TLibraryProc= procedure (Reason: Integer);

TMyCpx
private
 DllProc:TLibraryProc;

procedure LibraryProc(Reason: Integer);

implementation

procedure LibraryProc(Reason: Integer);
begin
...
end;

【cpxPilotStart】

//この関数が読み込まれたアドレスをインスタンス内に割り当てる
DllProc := @LibraryProc;//エラーチェック省略
DllProc(DLL_PROCESS_ATTACH);

【cpxFolderPilotStart】

Result := True;
if CritSec = nil then begin
 //割り当て済みのはずなのに、nilだから、エラーを出す。
 pICmnPilot.cmnStatus ('フォルダロックエラー',TRUE);
 Result := False;
end else begin
 //通常は、全てここに来る。
 pICmnPilot.cmnStatus ('フォルダロック獲得待ち・・・',FALSE);
 CritSec.Enter;
 //この後、獲得できるまで、全てのインスタンスがじっと待つ
end;

【cpxFolderPilotEnd】

CritSec.Leave;//後始末して解放

宣言あたりが、訳わかんなくなってきた。(^◇^;)

こうでしょうか?
やっぱり、マルチスレッドに関して、いまいち理解が足らないかも。(^◇^;)

>うーむ、Delphiはどーにもよく判らない・・・

> end else begin

あたりが、Cっぽいですね。
このあたりは、好きずきみたいです。
テンプレートあたりの記述を見ると、

if (...) then
begin
......
end
else
begin
......
end;

などが、基本みたいです。
この書き方の場合、beginとendが、必ず同じ位置に来るので、対応関係が分かりやすくなります。
行は増えますが、対応関係が分かりやすいので、入り組んでいる部分を中心に、こういう書き方をしています。

----
YOS cra-top.yoshida@nifty.com by CMN 0.50β + YosPad 1.35
http://com.nifty.com/community/C0023097/top.go

タイトルRe7: CPXについての質問2件
記事No35
投稿日: 2005/11/21(Mon) 16:55
投稿者うぇいく
 こんにちは。

>>2.ユニット変数を宣言
>これは、スタティックに確保していると言うことですね。
>で、同一CPX、つまり、各巡回フォルダを巡回するCPXから、共通して参照されると言うことで。
のようです。

>>4.初期化処理(ユニットの手続き)を追加
>このように、DLLの関数呼び出しみたくアドレスを割り当てるのは?
>これは、cpxFolderPilotStartあたりに書いておくのかな?
>えーと、cpxPilotStartかな?
いえ、ユニットそのものに(?)記述します。
ユニットのend.の寸前に、beginをつけて記述してみてください。
# ユニットが読み込まれたとき(DLLでは初期化処理)に実行される処理になる・・・・よーです。1つのプロセスから何度ロードされても、1回しか実行されません・・・・のはずです
# もちろん、一旦全て開放してから再度呼び込まれた場合は新たに呼び出されます・・・・たぶん。

>>5.フォルダ開始時にロックを確保を追加
>あれ?CritSec.Enterが、ここにしかないですね。
>つまり、CriticalSectionに入って何かするのではなく、CriticalSectionには入れたかどうかで、判定すると言うことかな?
1つのスレッドで、Enterを発行してからLeaveを発行するまでの間が排他されます。

>この場合、ほぼ同時に要求する場合、どうなるんだろう?
後から要求したほうがまたされます。つまり、ロックを獲得できれば、Enterから復帰してきますが、獲得できなければ復帰してきません。
# 「ロックを取れるかどーか問い合わせるだけ」というmethodもあります。

>えーと、以上から、想像を書きます。
〜略〜
>TMyCpx
>private
> DllProc:TLibraryProc;
DllProcは、Delphiのsystemパッケージが持つグローバル(?)な変数(?)です。別途宣言する必要はありません。

>//この関数が読み込まれたアドレスをインスタンス内に割り当てる
>DllProc := @LibraryProc;//エラーチェック省略
>DllProc(DLL_PROCESS_ATTACH);
これは、DLLのメインのユニットそのものに記述。class/package/function/procedureには含まれません。
# しいていえば、initialization区。
DLLのロードに対して1度のみ実行したいわけですから、それがOSから保証されている部分に記述します。

>やっぱり、マルチスレッドに関して、いまいち理解が足らないかも。(^◇^;)
TCriticalSectionをCreateすると、OSからバトンを1つもらいます。その後、Enterを発行すると、バトンを貸し出し中にして呼び元に復帰するわけです。そして、Leaveを発行することで、バトンを返却済みするわけです。もし、Enterした際にすでにバトンが貸し出し中の場合は、バトンを返却されるまで、永遠に待ちます。
# TCriticalSectionが楽な点は、バトンが常に1つで、「ほしい」「返す」「今あるの?」の制御しかない点です。複雑なことは出来ない代わりに、利用も簡単です。気をつける点は、TCriticalSectionのインスタンスを、管理したい対象内で1つにすること です。通常、ごく短い処理に対して使用します(※)。

>この書き方の場合、beginとendが、必ず同じ位置に来るので、対応関係が分かりやすくなります。
>行は増えますが、対応関係が分かりやすいので、入り組んでいる部分を中心に、こういう書き方をしています。
 Cやjavaでも、{}が同じカラムに来るように記述すほうが多いようです。まとめちゃうのは画面が狭かったころの名残りですね(笑)
# エディッタが面倒見てくれるから、カラム合わせるよりも、見渡せる範囲を広くしたほうが読みやすい というのもあります。begin/endは面倒見てもらえませんが(笑)

※mixiでいえば、以下のような処理を実装して、その部分のみに実装するような感じだとスマートです。
 ・共有エリアに最終アクセス時刻(通算秒)を保持するエリアを持つ。
 ・アクセスチェック要求がきたら、
  ロック獲得→通算秒チェック→
   アクセス間隔OK→通算秒更新→ロック解除→チェック処理を終了
   アクセス間隔NG→ロック解除→少しsleepして最初に戻る
 ようは、共通的にアクセスされる通算秒への参照・更新のみ排他するわけです。ほんとに排他したいのは、webへのアクセスだけですからね。


なお、Dllのロードに合わせるのではなく、PilotStart/PilotEndを信じて、そこで、TCriticalSectionのCreate/Freeを行うのでも動作するはずです。その場合は、DllProcへの代入やLibraryProcを忘れて、TCriticalSectionのCreateをPilotStartで行い、FreeをPilotEndで行ってください。
# その場合でも変数自体は、スタティックに持つ必要があります。FolderStart/FolderEndはそのまま。
-- CMN v0.50β --

タイトルRe8: CPXについての質問2件
記事No36
投稿日: 2005/11/21(Mon) 19:41
投稿者YOS   <cra-top.yoshida@nifty.com>
#35 うぇいくさん、こんにちは。

># ユニットが読み込まれたとき(DLLでは初期化処理)に実行される処理になる・・・・よーです。1つのプロセスから何度ロードされても、1回しか実行されません・・・・のはずです

調べたところ、そうみたいですね。
きっと、DelphiのDllProcヘルプだけでは、とうてい理解できませんでした。

># 「ロックを取れるかどーか問い合わせるだけ」というmethodもあります。

TCriticalSection.Acquireでしょうか?
これそのもののヘルプがないので、想像ですが。

>DLLのロードに対して1度のみ実行したいわけですから、それがOSから保証されている部分に記述します。

なるほど。

># エディッタが面倒見てくれるから、カラム合わせるよりも、見渡せる範囲を広くしたほうが読みやすい というのもあります。begin/endは面倒見てもらえませんが(笑)

それが理由だったんですね。
たしかに、Cなどでは、それに対応したエディタがあり、便利みたいですね。
begin/endは、{}に比べて目立つため、Cの様なサポートをするよりも、字下げで対応した方が見通しが良い、と言うことなのかも知れません。

> ようは、共通的にアクセスされる通算秒への参照・更新のみ排他するわけです。ほんとに排他したいのは、webへのアクセスだけですからね。

確かに、その通りです。
mixiの場合、CMNの処理速度が速いため、処理時間は、ほとんど無視できるレベルという前提で、単純にスリープさせています。
要は、こんな高度な処理が、思い浮かばなかっただけですけど。

>なお、Dllのロードに合わせるのではなく、PilotStart/PilotEndを信じて、そこで、TCriticalSectionのCreate/Freeを行うのでも動作するはずです。

とりあえず、これで行っています。
TCriticalSectionを使う代わりに、泥臭く、ロックフォルダ作成で行きました。
これなら、ほぼ同時に作成要求を出しても、Winが、はじいてくれるようで、そのエラー処理さえ実装しておけば、排他処理が、可能みたいです。

グローバル変数の理解が不十分で、いまいち、怖さがあったんです。

おかげさまで、マルチスレッド環境において、一つのスレッド内で複数のインスタンスを扱う環境から呼び出されるDLL内で排他処理を行う、と言うことに関して、だいぶ、分かってきました。

とりあえず、複数フォルダでも問題なく巡回可能な事を実現出来たら、ゆっくり対応していきます。

----
YOS cra-top.yoshida@nifty.com by CMN 0.50β + YosPad 1.35
http://com.nifty.com/community/C0023097/top.go

タイトルRe9: CPXについての質問2件
記事No38
投稿日: 2005/11/22(Tue) 16:29
投稿者YOS   <cra-top.yoshida@nifty.com>
#36 うぇいくさん

>とりあえず、複数フォルダでも問題なく巡回可能な事を実現出来たら、ゆっくり対応していきます。

とか良いながら、コメントアウトした状態で、ソースに入れ込んじゃいました。
あとからになると、忘れそうなんで。(^^;ゞポリポリ

----
YOS cra-top.yoshida@nifty.com by CMN 0.50β + YosPad 1.35
http://com.nifty.com/community/C0023097/top.go