🗐 電装工芸日記 - 舞台照明機器の製作とか -

能登半島地震で被災された方々にお見舞い申し上げます。

or 管理画面へ

2023年1月 この範囲を時系列順で読む この範囲をファイルに出力する

Icon of admin
 共有メモリの衝突回避ですが、共有メモリの中にハンドシェイク表すフラグを入れたらそれでいいんじゃないかと。
 そのフラグが立っていれば極々わずかな時間sleepを繰り返す処理です。

while(flag1 == 1)
{
 sleep(0.001);
}
flag2 = 1;
/* 共有メモリ処理 */
flag2 = 0;


 みたいなものです。
 別プロセスがフラグを0にすればwhileを抜けます。
 簡易的なモノですが、フラグを書き換えられるプロセスを一つにしておけばイイんじゃないかと。最も簡単なセマフォはこういうことですし。

 子プロセスの停止制御も同様の考え方が使えます。
 動作し続けるってことは繰り返し処理です。単なる繰り返しはwhile(1)とかで無限ループすることが多いので、while(flag==1)とかにすればいい。共有メモリ上のフラグが1ならwhileでループし0になったら抜ければいいのです。抜けたら終了処理をしてプロセスを落とすと。子プロセスが完全に終わったことはスタックしておいたプロセスIDを見ればわかります。

 この辺りまで決まれば次はランチャーです。

#C言語
Icon of admin
 共有メモリに構造体を配置してみましたが、割と簡単でした。
 構造体のタグ(ひな形)をヘッダーファイルに作り、親プロセスと子プロセスにinclude。共有メモリのサイズは構造体のタグから得て設定。共有メモリ上に置く変数を独立したポインタにするとオフセットをそれぞれ計算して与えないといけませんが、構造体なら一括設定出来て便利です。
 構造体をポインタにすると表記が独特になりますが、意味合いが明示的となって読みやすいかもしれません。
 この辺りには、本文中に出来るだけ定数を直書きしないという方針にも繋がってきます。

 次は共有メモリの衝突回避を調べないといけません。

#C言語
Icon of admin
 屋外で開催される成人式関連のイベントで電源出しです。
 起動してしまえばやることはありません。
 本日の課題は共有メモリのテストです。

 次のページにあるソースをそのまま使って挙動を確認です。
 プロセス間でのメモリ共有

 親プロセス「ShareMemTest1」を起動した後、待機時間(20秒)のうちにコンソールで「ShareMemTest2」に共有メモリのIDを与えて起動するというもの。一貫したプログラムではありませんが、やりたいことはプロセス間でのメモリ共有ですからむしろわかりやすい。
 ちなみに、コンソールでプログラムを起動する際、末尾に「&」を付けると新規プロセスで実行します。

 ここサンプルを使うなら、

 <親プロセスを起動>
$ ./ShareMemTest1 &

 <起動後表示>
nShareMemID = 23 /* IDは都度変わります */
process1 : nVar1 = 1, nVar2 = 2
・・・ここで20秒Sleepしてます・・・

 <子プロセスを起動>
$ ./ShareMemTest2 23 &

 <起動後表示>
nShareMemID = 23
process2 : nVar1 = 1, nVar2 = 2
process2 : nVar1 = 2, nVar2 = 2
・・・子プロセスはここで終了・・・

・・・20秒後、親プロセスが再開・・・
process2 : nVar1 = 2, nVar2 = 2
・・・親プロセスも終了・・・

 となります。
 正に記述にある通り。

$ ipcs -m
 や
$ free
 を用いるとSharedメモリの状況がわかります。

 実際のテストではgetpid()を用いてプロセスIDも表示しながら確認しましたが、確かに別プロセスでした。
 共有メモリの容量は、無意味に8MBくらい設定してみましたが何の問題も無し。

 親側の設定は、typedefで構造体を定義し、構造体のポインタ変数を作り、構造体のメモリサイズ(sizeof()で取得)をもとに共有メモリを作り、構造体のポインタ変数に共有メモリを割り当てる、といった流れでしょうか。
 子側は、typedefで構造体を定義し、構造体のポインタ変数を作り、親から取得したIDから構造体のポインタ変数に共有メモリを割り当てる、といった流れ?
 共有メモリ上に変数(構造体)を構築した後は共有メモリを意識する必要は無いと思います。もちろん、衝突回避は常に考えないといけませんけど。

 勘違いしていた点ですが、共有メモリのIDは管理用の通し番号であってポインタに設定するアドレスではないことです。C言語では何かにつけてポインタ渡しなのでこれもそうかと思ってしまいました。

 共有メモリに構造体を配置することが次の課題ですが、構造体についてもう少し勉強してからです。

#C言語
Icon of admin
 C言語の基本的な書き方は整理がついてきました。
 次はライブラリの理解と使い方となるのですが、ネットで検索しても情報があるっちゃあるけどイマイチ感。
 基本に立ち戻れば、ライブラリのman(公式のマニュアルファイル)とヘッダーファイルを読めとなります。以前からそうするのが王道とは思ってはいましたが、何が書いてあるのかサッパリでした。
 それが少しわかるようになってきました。我ながら大進歩。
 manはLinux系のOSなら本体にも必ず入っているものの英文が多いのですが、ネットで検索すると日本語版がすぐに見つかるのでこちらを読んだ方がいいかも。
 かといってman読めばいいかと言えばそうでもない。前触れもなく突然出現する用語やパラメータが多い。
 ようやくわかったのですが、ライブラリのmanはヘッダーファイルを補足しているに過ぎないらしい。つまり、ライブラリを理解するための主役はmanではなくヘッダーファイルということ。
 変数の型定義、構造体の定義、プロトタイプ宣言などが書かれているヘッダーファイルは定義書であり解説書でもありますので、これを読み解けない人がC言語でプログラムを書けるワケないでしょう・・・という熟練者たちのご意見はその通りです。
 どこを読むべきか、何を理解するべきかが見えて来ただけでも今日のところはいいんじゃないかと。

 早速、socketのライブラリである sys/scoket.h を読んでみようと /usr/include を覗いたのですがありません。
 google様に教えてもらい、次のコマンドで在処を検索できました。
 $ sudo dpkg --search sys/socket.h
 結果は /usr/include/arm-linux-gnueabihf/sys/socket.h とのことでした。
 パッと見ではサッパリわかりませんが、半分くらいはわかるので、全体を理解出来る様に頑張ってみましょう。

#C言語
Icon of admin
 現場が早く終わったので、開発用のRaspberryPiをノートパソコンのVSCodeと繋いでおきました。ここまでしておけば比較的身軽に開発が出来ます。
 本格的に開発を進めましょう。

 C言語でのsocketについて調べてみましたが、PythonのscoketライブラリはC言語のsocketをほぼそのまま橋渡ししているだけみたいです。引数の書式にわずかな違いはありますが、ほぼ同様に使えそうです。Art-Netを受信してそのまま転送する処理から試しましょう。

#C言語 #[Art-Net]
Icon of admin
 C言語はプロセスの管理方法を調査中です。
 直近の課題はAr-Netパッチです。この機構は大きく分けて、(1)Art-Netエンジン(受信、パッチ、送信)、(2)DMXの状況モニタ表示、(3)ユーザーからのコマンド操作となります。
 C言語で書けば主な機能をスレッドに分ければいいような気もしますが、スレッドを分けるのもプロセスを分けるのも手間は大差ないので、プロセスを分けておけばいいかなと。

 先日も書きましたが、ランチャー的な親プロセスから各機能を子プロセスとして起動しようと思っています。これなら親プロセスで共有メモリを定義して子プロセスにポインタを渡すことが簡単だからです。また、子プロセスとして起動するなら親プロセスがプロセスIDを確実に把握出来ますので管理上のメリットもあります。
 まだわからない調査中のことは、子プロセスの終了のさせ方です。killコマンドでプロセスを消す方法はありますが、後処理(設定の現在値の保存など)をしてから子プロセスを終了したいので、有無言わさずプロセスを消すkillコマンドはよろしくありません。望ましいのは、親プロセスからコマンドを送って子プロセス自身で終了させることです。Python的に考えるなら、親プロセスからの指示で子プロセスに何かしらの例外が発生してwhileをbreakで抜け出すような処理です。共有メモリでコマンドをやり取りするのが現実的だと思いますが、出来るだけシンプルで汎用的な方法を構築したいところです。

 いずれにしても、親プロセスから子プロセスを起動し、プロセス間で通信(変数の共有)をし、親プロセスから子プロセスを終了させる方法の定型化です。

 もう少し学習が進んでからになりますが、共有メモリの挙動も調査しないといけません。
 共有メモリは複数のプロセスから読み書きできるメモリ空間ですが、マネジメントされていませんので衝突(読み書きの処理タイミングが被ること)による不整合が起きる可能性があります。これを回避する手段としてセマフォなどの機能があるのですが、出来るだけシンプルな方法を見つけたいと思っています。
 調査したいのは、共有メモリに書き込み出来るプロセスを唯一とし、他のプロセスは読み出しのみとした場合にどうかという点です。機能的に共有メモリの読み書きは頻繁に行われますので出来るだけ手数を少なくしたいのですが、結果的に書き込みのタイミングをマネジメントしなくていいなら手数は最小だし、何かが必要だとしてもどこまでやるのかを知りたいワケです。

#C言語
Icon of admin
 VSCodeのSSH環境作りは予想外に簡単でした。
 自宅でファイルサーバーになっているRaspberryPiに接続してC言語の実習をしております。
 まずは基本であり多用するであろうポインタによる関数の呼び出し方です。ポインタはその昔挫折した要素でありますが、どうも勘違いのままアタマに刷り込まれてしまったようで、わかっているつもりなのに間違った組み立てが浮かんできます。これは正しい組み方を刷り込み直すしかありませんので、自分なりの課題で実験を繰り返すしかありません。
 つい先ほど整理出来たのですが、ポインタ変数は定義した直後はnull値であって特定のアドレスは持っていません。int *num では実体の変数は定義されないということがわかったのですが、正にこういった点がその昔の勘違いなんですよね。「ポインタは実体変数の扱いを補助するための機能」という前提がアタマに入ったのでスッキリしました。「実体ではない」ということが明確になっただけでも私の中では大革命です。

 あと、インクリメントとデクリメントについてメモ。
 C言語では++numと書かないと期待値になりません。雰囲気的にnum++と書いてしまいがちですが、エラーにならんのにインクリメントされんのです。
 デクリメントも--numとしないといけません。
 計算記号が行頭にあっていいのかって疑問が湧きますが、慣用句として覚えておきましょう。

 それにしてもVSCode+SSH+gcc+gdb環境は便利ですねぇ。
 コンパイルから実行までの手数や所要時間が画期的に短い。エラーも丁寧に教えてくれるし、メモリがマネージされているからヘタなモノ書いてもシステムが飛ぶこともない。スクリプト言語をチョイチョイ書いているのと大差ありません。
 デバッカーのお世話になるレベルになるにはまだまだかかりそうですが、こんなに簡単にC言語が扱えるなんて私の中では画期的過ぎです。25年前と一緒にすんなって話ですけどね。

#C言語
Icon of admin
 Windows上のVSCodeからSSHでRaspberryPiに接続してコードを編集・コンパイル・実行してみました。
 コードは俗に言う「Hello, World」。コンソールに簡単な文字列を表示するだけのモノです。
 VSCodeはユーザーインターフェースのデザイン更新が頻繁なのか、ネットの解説は出来るだけ新しいモノを参考にしないと見た目が違います。
 インストールと設定は次の通り。

 まずはRaspberryPi側から。sshでつながることを前提とする。
1)対象となるRaspberryPiをアップデート
 $ sudo apt update
 $ sudo apt upgrade
2)build-essentialをインストール。
 $ sudo apt install build-essential
 デバッカーのgdbが必要になる、上記で入らなかったらインストール
 $ sudo apt install gdb

 Windows(11)側
1)VSCodeをダウンロード
 https://code.visualstudio.comってのが本家みたい。
 環境に合わせてインストーラーをダウンロード
2)インストール
 ダウンロードしたインストーラーを起動して初期設定のまま進めてインストール。選択項目がある場合はよくわからんけど一番上を選択。
3)起動後、機能拡張の日本語パックを入れる(参考ページは呆れるほどあります)
 機能拡張のメニューから「Japanese Language Pack for Visual Studio Code」をインストール
 インストール後、アプリを再起動すると大半のメニューが日本語になっています。
4)同じく機能拡張の「Remote Development」を入れる
 他に必要な機能拡張は自動的に入ります。
5)ssh接続してみる
 以下を参考にすれば繋がると思います。
 「Visual Studio Codeを使ったC言語リモートコンパイルからリモートデバッグまで」
6)初回接続ではRaspberryPi側にも色々入れるようで少し時間がかかります。
7)この他にも自動的に入った機能拡張がありますが、よくわからんのでここには書きません。

 Windows上のVSCodeでコーディング、コンパイル、デバッグ、実行が出来ました。
 ブレークポイントありのデバッカーまで使えるのですから、Turbo-CのトラウマでC言語を敬遠していた時間が勿体ないと思える程に便利です。

#C言語
Icon of admin
 新年あけましておめでとうございます
 本年もよろしくお願い申し上げます

 さて、さかのぼること大晦日の夕方、実家に顔を出そうと思ったのですがどうも熱っぽい。計ると37.2度。
 ダルさは若干あるものの、抜けきっていない疲れなのか、流行り病の前兆なのかわかりません。
 大事を取って自宅に引きこもり。
 暇なんでRaspberryPiをC言語で開発する環境についてアレコレ調べています。
 大晦日に何してんの?って突っ込みは正しいと思いますが、外出出来ないのだから仕方ない。

 PythonはTeraTermでSSH接続してRaspberryPi上のViとかnanoとかで書いていました。debianに標準搭載のテキストエディタです。Windows上で操作すればコピペも出来るので特に不自由はありませんが、色々調べるウチにVSCodeが便利そうで使いたくなりました。C言語はカッコや行末のセミコロンを忘れてコンパイルエラーになることが多いのですが、これを防止する為だけに使っても意味があります。
 世の中進歩するというか便利なツールを作ってくれる貴兄がおりまして、VSCodeはプラグインを入れるとSSHで完全にリモート操作が出来る。コーディングはもちろんのこと、コンパイルもデバッグも出来るとのこと。すばらしい。
Visual Studio Codeを使ったC言語リモートコンパイルからリモートデバッグまで
 ゼロから設定するなら本文中にあるリンク「参考にした解説」も読む必要があります。
Visual Studio CodeでLinux ホストリモート開発
 ちょっと面倒ですが、SSHでリモート開発したいなんて考える人ならそれほど苦にならないでしょう。

 VSCodeは様々な言語をサポートしてくれる超絶強力なコーディングエディタです。

#C言語

2022年12月 この範囲を時系列順で読む この範囲をファイルに出力する

Icon of admin
 2022年の大晦日です。
 コロナの感染拡大は完全に収まりはしなかったものの、仕事ではその影響も和らぎ忙しくさせて頂いた一年でした。
 ご協力を頂いた各方面の方々に改めて感謝申し上げます。

 ただ、体力的には過負荷が続いたもので、年末休暇に入ってからの2日間は完全にシャットダウン。大晦日の今日になってようやく普通に戻ってきた感じです。
 年末にやるべきことの大半が出来ませんが、少しはこなして実家にも顔を出しましょう。
 C言語の書き方は妄想だけなので合間に少し進めます。

#雑談

■当面の課題

桜のライトアップの季節です。花粉症の季節でもあります。
自分は平気ですが、花粉症の部下は死にそうな顔をしています。

編集

■複合検索:

  • 投稿者名:
  • 投稿年月:
  • #タグ:
  • カテゴリ:
  • 出力順序:

■日付検索:

■カレンダー:

2023年1月
1234567
891011121314
15161718192021
22232425262728
293031

■カテゴリ:

■最近の投稿:

最終更新日時:
2024年4月27日(土) 21時39分45秒