問題タブ [posix]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 基本的なスレッドの概念/競合状態を支援する
私は今POSIXスレッドについて学んでいますが、これはマルチスレッドに関する一般的な質問にすぎないと思いますので、誰かが私を助けてくれることを願っています。私が取り組んでいる本から、競合状態を示すこの例があります。
これについて私が理解していないことがいくつかあります。まず、「スレッド番号5」です。スレッド番号5にあるはずではありませんが、何度も印刷されます。この本では、例はスレッド8が何度も印刷されることを示しています。と言う部分もわかりません*(int *)thread_number
。これをthread_numberだけに変更しようとしましたが、それは私に何度も何度も奇妙な数字を与えました。
この本は実際にはこれを説明していません。誰かが私にここで何が起こっているのかを明確に説明してもらえますか?次のような印刷が行われない理由がわかりません。
「スレッド番号x」がマルチスレッド化されているので、私はそれを知っています。一部は異なる時期に提供されますが、作成したスレッドごとに1行の「スレッド番号x」が正確に10個ない理由がわかりません。
〜desi
serial-port - POSIX で半二重シリアル ポートにアクセスする
POSIX 呼び出し (より具体的には、Linux 2.6.x で C で記述) を使用して、半二重シリアル接続から読み書きするように求められます。その特定のモデルに関する詳細な情報を見つけるのに少し苦労しています (ほとんどのページは全二重に集中しています)。読むときに少し異常があるので、ここで何か間違ったことをしている可能性があるかどうかを確認したいと思いました。
半二重シリアル接続では、読み書きしかできません。これは問題ではありません。なぜなら、要求されていない受信データが回線上にないからです。パッケージが (読み取りのために) 私に送られるのは、事前に要求したときだけです。
したがって、私のコードは、何かを送信する必要があるたびにポートに write() することです。このデータが応答になる場合 (事前にわかっていること)、単純に read() します。私が呼び出している特別な関数はありませんが、そうすべきでしょうか? そして、このアプローチは正しいですか?すなわち、行が空いているときに書く?
signals - ゼロ除算による SIGFPE を無視できますか?
特定の状況で停止するために、故意にゼロ除算を実行する (そして結果を揮発性変数に格納する) プログラムがあります。ただし、ゼロ除算を実行するマクロを変更せずに、この停止を無効にできるようにしたいと考えています。
無視する方法はありますか?
使ってみました
ただし、「浮動小数点例外(コアダンプ)」というメッセージで停止します。
実際には値を使用しないので、変数に何が割り当てられているかはあまり気にしません。0、ランダム、未定義...
編集:これが最も移植性が高いわけではないことはわかっていますが、多くの異なる OS で実行される組み込みデバイスを対象としています。デフォルトの停止アクションはゼロ除算です。他のプラットフォームでは、ウォッチドッグによる再起動を強制するために別のトリックが必要です (割り込みを無効にした無限ループなど)。PC (Linux) のテスト環境で、assert などに頼らずに、0 除算での停止を無効にしたかったのです。
c - strerror_r にはどのサイズを許可する必要がありますか?
The Linux Standard Base Core Specification 3.1と同様に、OpenGroup POSIX.1-2001 はstrerror_rを定義しています。しかし、エラー メッセージに合理的に期待できる最大サイズへの参照が見つかりません。コードに配置できる定義がどこかにあることを期待していましたが、見つけることができるものはありません。
コードはスレッドセーフである必要があります。これが、strerror ではなく strerror_r が使用される理由です。
誰も私が使用できる記号を知っていますか? 自分で作成する必要がありますか?
例
ドキュメントから:
オープン グループ基本仕様第 6 号:
エラー
strerror_r() 関数は、次の場合に失敗する可能性があります:
- [ERANGE]生成されたメッセージ文字列を格納するには、strerrbuf および buflen によって提供されたストレージが不十分でした。
ソースから:
glibc-2.7/glibc-2.7/string/strerror.c:41:
posix - スリープ状態のスレッドでシステム時刻を変更すると、どのような影響がありますか?
すべての BSD で使用可能であり、実際には POSIX 標準の一部として定義されているclock_gettime()関数を見ると、少なくとも 3 種類のクロックがサポートされていることがわかります (多くのシステムでは、これらのクロックよりも多くのクロックがサポートされています)。 、しかし実際には POSIX 標準では 1 つの存在のみが要求され、他のすべてはオプションです):
CLOCK_REALTIME - POSIX はこれが存在することを要求します。これが壁掛け時計です。
CLOCK_MONOTONIC - これが何なのか (そして SI 秒が何を意味するのか) はわかりませんが、この時計が逆方向にジャンプすることはなく、値が単調に増加することしかできないことは理解しています。
CLOCK_UPTIME - これが CLOCK_MONOTONIC とどのように異なるのかわかりません (アップタイムも後方にジャンプすることはありません) が、少なくともカーネルの起動時にこのクロックがゼロから始まることはわかっています (一方、カーネルの起動時に CLOCK_MONOTONIC が持つ初期値は定義されていません)。 )
他の時計はしばらく無視しましょう。CLOCK_REALTIME が単調にカウントアップすることは保証されていませんよね? これが実際の「システム時間」です。システム時刻を自由に変更できます。過去 3 か月または未来 5 年間に設定できますが、システムがネット上の NTP サーバーを使用して時刻を同期するたびに、時刻が前後する可能性があります。
現在、BSD システムには 2 つのスリープ関数があります。sleep()とnanosleep()。確かではありませんが、sleep() が nanosleep の上に実装されることを期待します。結局、nanosleep() を使用して sleep() を簡単にエミュレートし、構造体の timespec で秒数を設定するだけで、ナノ秒をゼロに保つことができます。 .
私は多くの情報源で、これらの関数が実際にウェイクアップ時間を計算することで機能し(現在の時間を取得し、それにスリープ時間を追加する)、現在の時間がウェイクアップよりも遅いかどうかをシステムが定期的にチェックすることを読みましたその場合は、スレッドを再び起動します。これが間隔を置いてのみチェックされるという事実が、現在のスリープが少なくともこの時間 (信号によって中断された場合のみ) スリープするが、それより長くスリープする可能性がある (頻度によっては) とマニュアルページに記載されている理由です。システムは、ウェイクアップ時刻をすでに過ぎているかどうかをチェックし、スケジューラがこのスレッドの再実行を許可するまでの時間に応じてチェックします)。
これは私にとって完全に正気です...しかし、常に私を悩ませていた質問が1つあります。
さまざまな情報源によると、スリープ (少なくとも nanosleep) は内部でクロックとして CLOCK_REALTIME を使用します。つまり、nanosleep() に 30 秒間スリープするように指示してから、システム クロックを将来の 1 時間に変更すると、スレッドはほぼ即座にウェイクアップします (将来の 1 時間は、ウェイクアップ時間 nanosleep( ) 計算)。これも全然オッケーです。しかし、私が 30 秒で目を覚ますと言った後、ユーザーが自分のシステム時計が 1 時間進んでいることに気づき、時計を 1 時間遅らせたらどうなるでしょうか? 次に、私のスレッドは 1 時間 30 秒間スリープしますか? それはかなり悪いでしょう。
c++ - pthread_join - 複数のスレッドが待機中
POSIXスレッドとC++を使用して、一度に1つずつ安全に実行できる「挿入操作」があります。
pthread_join を使用して挿入を待機しているスレッドが複数ある場合は、終了時に新しいスレッドを生成します。それらはすべて一度に「スレッド完了」シグナルを受け取り、複数の挿入を生成しますか、または「スレッド完了」シグナルを最初に受信したスレッドが新しいスレッドを生成し、他のスレッドが新しいスレッドを作成するのをブロックすると想定しても安全ですか。
返信ありがとうございます
このプログラムは基本的に、ソケットを介してクライアントからの要求を受け取る巨大なハッシュ テーブルです。
新しいクライアント接続ごとに新しいスレッドが生成され、そこから複数の操作 (具体的にはルックアップまたは挿入) を実行できます。検索は並行して実行できます。ただし、挿入は単一のスレッドに「再結合」する必要があります。クライアントの新しいスレッドを生成せずにルックアップ操作を実行できると言えますが、サーバーがロックされて新しいリクエストがドロップされるまでに時間がかかる場合があります。この設計では、システム コールとスレッドの作成を可能な限り最小限に抑えようとしています。
しかし、最初に考えた方法では安全ではないことがわかったので、何かを一緒に石畳にできるはずです
ありがとう
c - マルチスレッドソケットアプリケーションへの変換
私は現在このプロジェクトをCでのみ行っているので、これまではWebサーバーをシングルスレッドアプリケーションとしてのみ使用してきました。しかし、私はもうそれを望んでいません!だから私は私の仕事を処理する次のコードを持っています。
fork();
これで、開始前に追加しました。これはProcessConnection();
、複数の接続を許可するのに役立ちます。ただし、この回答にあるアプリケーションをデーモン化するためのコードを追加すると、少し問題が発生しました。を使用fork()
すると、実行中のアプリ全体のコピーが作成されます。これがの目的ですfork()
。そこで、この問題を解決したいと思います。
私ProcessConnection()
はこのように見えます
connecting=socket = accept
一度に複数の接続を受け入れるようにするために、単に上または後に数行を追加するにはどうすればよいですか?使用できますfork();
が、DisposeCurrentConnection();
結局のところ、そのプロセスを強制終了して、親スレッドを実行したいだけです。
multithreading - POSIX キャンセル ポイントとは何ですか?
POSIX キャンセル ポイントとは何ですか? POSIX キャンセル ポイントの決定的なリストを探しています。
accept()
とselect()
キャンセルポイントと書いてある本を持っていたので質問していますが、インターネット上でそうではないと主張しているサイトを見たことがあります。
また、Linux のキャンセル ポイントが POSIX のキャンセル ポイントと異なる場合は、それらのリストも必要です。
c++ - getenv() を静的初期化子で、つまり main() の前に使用しても安全ですか?
私はStevensとPosix Programmer's Guideを調べましたが、私が見つけることができる最高のものは
プロセスが開始されると、 environmentと呼ばれる文字列の配列が使用可能になります。この配列は、次の
environ
ように定義される外部変数によってポイントされます。
extern char **environ;
私が躊躇しているのは、その環境変数です。私は言いたい
-呼び出し元のプロセス/シェルは、null で終了する文字列のブロックを既に割り当てています
-「外部」変数はgetenv()environ
によってエントリ ポイントとして使用されます。
-事実上、静的イニシャライザ内でgetenv()を自由に呼び出してください。
しかし、環境の「静的初期化」が他のすべての静的初期化コードに先行するという保証は見つかりません。私はこれを考えすぎていますか?
アップデート
私のプラットフォーム (AMD Opteron、Redhat 4、GCC 3.2.3) では、LD_DEBUGを設定すると、静的初期化子が呼び出される前に、 environが設定されることが示されます。これは知っておくと便利です。ありがとう、@コードロジック。しかし、必ずしもすべてのプラットフォームで得られる結果ではありません。
また、C/C++ ランタイム ライブラリの動作について @ChrisW に直感的に同意しますが、これは経験に基づく私の直感にすぎません。したがって、静的イニシャライザが呼び出される前にEnvironが存在することを保証する信頼できる場所からの引用をパイプできる人は誰でも、ボーナスポイントです!
c - パイプの読み取り側が現在ブロックされているかどうかを調べる
子プロセスがユーザー入力を待っているかどうかを調べようとしています (出力を解析せずに)。Unix の C で、パイプの読み取り側に現在 read() 呼び出しがブロックされているかどうかを判断することは可能ですか?
問題は、子プロセスで実行されるプログラムを制御できないことです。それらは、私が通常 /dev/null にリダイレクトしたいあらゆる種類の冗長なガベージを出力します。時折、ユーザーに何かを求めるプロンプトが表示されます。(プロンプトには信頼できる形式がありません。)したがって、私の考えは次のとおりです。
- ループ内:
- 子の stdout を排出し、一時バッファに追加します。
- 子がユーザー入力を求めているかどうかを確認します (方法はわかりません)。その場合、バッファーは標準出力に出力されます。
- 子が終了したら、バッファを破棄します。