トップページ⇒tech
1001コメント288KB

C言語なら、俺に聞け! <15>

■ このスレッドは過去ログ倉庫に格納されています
0001Dennis RitchieNGNG
漏れは38才、21年間プログラムを一生懸命作ってきた。
いろいろな言語を極めたが、一番手になじむのはCだった。
Cのことならぜんてわかるから、疑問な点があったら漏れに聞け。

だが、いちいちFAQに載った質問に応えるほど暇じゃない。
課題丸投げなら別スレにいけ。

・comp.lang.c Frequently Asked Questions
http://www.eskimo.com/~scs/C-faq/top.html

・C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html

Cプログラマならこれを買っとけ。
・プログラミング言語C(K&Rと呼べば通だ)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/yfcbookshelf-22/250-3950205-1475419

推薦図書/必読書のためのスレッド PART2
http://pc.2ch.net/test/read.cgi/tech/1010312992/l50

・前スレ C言語なら、俺に聞け! <14>
http://pc.2ch.net/test/read.cgi/tech/1015286974/l50
0002デフォルトの名無しさんNGNG
お、きたきた
0003デフォルトの名無しさんNGNG
今田げとー
0004デフォルトの名無しさんNGNG
4げとー
0005デフォルトの名無しさんNGNG
fork について聞きたいのですが、
これを使うとプログラム中に子プロセスが作られますが、自分の予想では、
その子プロセスもforkを使って子プロセスを作って、そのまた子プロセス
もforkを使って...という風に無限に続くと思ったのです。しかし
いざプログラムを組んでやってみるとどうやらforkは一回しか使われて
いないようなんです・・・ forkで作られた子プロセスはいったいどういう
動きをするのでしょうか?教えてください。
0006デフォルトの名無しさんNGNG
forkのあと親と同じ状態でスタート
0007デフォルトの名無しさんNGNG
なんだぁ、>>1の名前に期待してたのに・・・
0008デフォルトの名無しさんNGNG
プロフィールが日下部のままなのが笑える
00095NGNG
/*ヘッダは省略*/

int main(void)
{
pid_t pid;
char *message;
int n;

pid = fork();

switch(pid)
{
case -1:
/*エラー*/
exit(1);
break;
case 0:
message = "This is the Child";
n = 5;
break;
default:
message = "This is the Parent";
n = 3;
break;
}

for(; n>0 ; n--){
puts(message);
sleep(1);
}

/*以下省略*/

}

というようなプログラムなのですが(書籍:Linuxプログラミングより) 6さんの言ったことは
”子プロセスはforkの次の行から処理を実行する”ということで合ってますか?
0010デフォルトの名無しさんNGNG
ぜんてってなんだよ。アレンジにしてはひどいな。
0011勉強中NGNG
#include <stdio.h>
static int i = 1;
extern int i ;
int main(void)
{
printf("%d",i);
return 0;
}

エラーにならないのは何故ですか?
これはどういうことでしょうか?
0012デフォルトの名無しさんNGNG
>>1
2ちゃんではリッチーと日下部が同列なのかよ...
0013デフォルトの名無しさんNGNG
子プロセスはfork()から0が帰ってきたように振る舞う。
が正しい。
「次の行から」という認識は間違っているぞ。
0014デフォルトの名無しさんNGNG
>>10
全て=ぜんて
このスレの慣わしです
0015デフォルトの名無しさんNGNG
>>11
どうしてエラーになるの?
0016デフォルトの名無しさんNGNG
staticを外してみよう
0017デフォルトの名無しさんNGNG
extern int i;

は、「 i という識別子が外部スコープにあるからそいつをint型として扱ってくれよろしく。」と読め。

static int i = 1;

は、
「iというint型変数をこのスコープに宣言する。staticなんで他のファイルからは見えないからよろしく。
初期化は1で。」

と読め。

どちらも矛盾していない。


0018勉強中NGNG
ご丁寧にありがとうございました<(_ _)>
確かに矛盾してませんね。
0019デフォルトの名無しさんNGNG
>>17
この場合、出力している i はどっちになる?
0020仕様書無しさんNGNG
static int i;
0021デフォルトの名無しさんNGNG
>>20
extern で手に入れた外部の i を利用するときは?
0022デフォルトの名無しさんNGNG
staticとexternは名前空間が別なのか...
初めて知った。
0023勉強中NGNG
ついでに関数などでexternalなiを使う方法は無いですか?
普通にiを使えばstaticな方を全て指すようになるから無理ですか。

0024デフォルトの名無しさんNGNG
そもそも外部変数を参照しようというのが設計的にしょぼいっツーか
スパゲッティの元なので、

extern int GetXXXDataI();
extern void SetXXXDataI(int i);

でも作って、他のファイルスコープにあるデータは
setter/getterを経由して参照しなさい。
002517NGNG
ついでにいうとお前>>22は何か勘違いをしている。
0026デフォルトの名無しさんNGNG
>>24
禿しく同意
0027デフォルトの名無しさんNGNG
>>24
おれもそんな感じにオブジェクトファイルを
クラス風に見立てていつもやってるんだけど、
これって正しいやり方なのかな?
0028デフォルトの名無しさんNGNG
Cではよくあるやり方でないかい?
0029デフォルトの名無しさんNGNG
>>28
ちと安心した
0030デフォルトの名無しさんNGNG
>>7
次スレはお前がたてろ。
面白くなければ死刑に処す。
0031勉強中NGNG
ごめんなさい、スパゲッテエェはもう作りません。
0032デフォルトの名無しさんNGNG
Σ(´-`).。oO(>>1の名前がリッティジャン・・・haxahaax)
0033デフォルトの名無しさんNGNG
static int i;
int ii;
int main()
{
 ・・・
これら二つの変数が異なるセクションに確保されるのは
言語的に決められているんでしょうか?
0034デフォルトの名無しさんNGNG
識別子が違うし刈りの定義は0で初期化されるし
じゃなくて>>1さーん
リッチィ先生は38歳じゃないよぉ・・。
50〜60歳?いいお年だな( ;´Д`)堪らないねぇハァハァ
0035デフォルトの名無しさんNGNG
違いはスコープだけで、置かれる場所は同じだ。

int ii;は他のスコープからextern int ii;かなにかで参照され得るが、
static int i;は、ファイルスコープ内からしか合法的に参照されることはない。

0036デフォルトの名無しさんNGNG
リッチィ先生のティンポ、、ハァハァ
00375NGNG
>>13
"子プロセスがforkを呼び出しても孫プロセスは作らずに0を返す"
と思っておけばいいでしょうか?
0038デフォルトの名無しさんNGNG
>>37
永遠に子供を産むことが出来ます。
子供の子供の子供の・・・
0039デフォルトの名無しさんNGNG
あるのはプロセスを作った方(=親)と作られた方(=子)という関係だけで、
ある子が、forkでプロセスを作ったとすれば、またそこで親と子の関係がひとつできあがる。

子がforkを呼べば、孫プロセスが作られ、孫プロセスのpidが返る。
0040デフォルトの名無しさんNGNG
そもそもお前らのプロセスはみんな init(0)の子なんだよ。(UNIX系限定)
0041デフォルトの名無しさんNGNG
実際のプログラムを作るときには
プロセスグループ、セッショングループとかが
関係してくるからStevens大先生の本を読むのが
いいよ。
おれはあんまり詳しくないから説明できない、スマソ
0042デフォルトの名無しさんNGNG
子供は、たとえ死んでも 親が生きてる限りゾンビとして残りますよね?
親子の縁を切りたいときはどうすればいいのでしょうか?
0043デフォルトの名無しさんNGNG
setpgid()
0044デフォルトの名無しさんNGNG
ごめん、43は勘違い。うそでした。
0045ちょい教えてNGNG
IEのバージョン6のPCユーザーにメールを送るとアクティブXが
引っかかってメールが開けないらしい。こんなことってあるの?
もし、このアクティブXをメール送信者から制御できるいい方法ってある?
00465NGNG
>>42
どうやるんですか?ギブアップです。
wait使うとか?
0047デフォルトの名無しさんNGNG
>>45
わけわからん。
っていうか、ここで聞く話題なのかよ。
0048デフォルトの名無しさんNGNG
まずウイルスチェックすれ。
0049デフォルトの名無しさんNGNG
誰かこのスレの過去ログ取ってる奴いないか?
いたら是非アップしてほしいのだが。
0050デフォルトの名無しさんNGNG
>>46
- wait()系の関数で終了を待つ
- signal()などでSIGCHLDのハンドラにSIG_IGNを設定する
- sigaction()でSIGCHLDのフラグにSA_NOCLDWAITを設定する(Linuxではダメらしい)
どれでも可。他にも方法があるかも知れない。
0051デフォルトの名無しさんNGNG
あ、これは子が先に死んでもzombieにならない方法だけど、親子の縁を
切るわけじゃないから子から見たppidは変わらないんだな。

>>50の後に更に子がfork()して孫を作って、子はすぐに死ぬようにすれば
残った孫はorphan processとしてinitが引き取ってくれるから、完全に
親子の縁を断ち切れるかな。
0052デフォルトの名無しさんNGNG
仕事は子ではなく孫にやらせよう。
孫を産んですぐ死ぬ。
0053デフォルトの名無しさんNGNG
孫は生めない
0054デフォルトの名無しさんNGNG
そんなときは定番のUnix Programming FAQ。

[どうすればゾンビプロセスができることを防ぐことができますか? ]
http://www.adl.nii.ac.jp/~moro/unix-programmer/faq-j_2.html#SEC13

>>52
デーモン作るときの常套手段ですね。
00555NGNG
forkは本屋で参考書を立ち読みしてきて理解しました。
"一回の呼び出しで二回帰る"こんなの自分の持っている本には書いてませんでしたよ・・・

プロセス関係のこと、なんか面白そうなのでいろいろ調べたいと思います。いろいろお世話になりました
0056デフォルトの名無しさんNGNG
>>55
ちょっとまった!
そんなの聞いたこと無いぞ。<二回帰る
0057デフォルトの名無しさんNGNG
>>55
子プロセス自体はmainから始まるんじゃなくてfork()の後から
実行するってだけだよ。その時に親の使っていたメモリ領域を
そっくりそのままコピーする(厳密には最近のOSはどれも
データセクションの書き換え時に初めてコピーするようになってるけど)。
違うのはfork()の戻り値だけ。
0058デフォルトの名無しさんNGNG
制御系のC言語ってどんなのやるの?インラインアセンブラですか
0059デフォルトの名無しさんNGNG
GUIがないだけ。
だまされるな。
*や*る*こ*と*は*同*じ*だ*
0060デフォルトの名無しさんNGNG
>>58
ほぼ一緒。ただやたらとIOポートへのポインタを多用するだけ。
後、intが16ビットで懐かしい気分に陥ってみたり。
006158NGNG
>>60
ありがとうございます。ポインタですか・・・

0062デフォルトの名無しさんNGNG
>>58
インラインアセンブラもたまに使います。
CPUのレジスタに直にアクセスする場合等。
特に割り込み関係。
OS載ってれば別だけど。
0063デフォルトの名無しさんNGNG
インラインアセンブラもなにもCは皮かぶったアセンブラだよ。
ポインタはCの中で特に強くアセンブラ的な要素をもったもの。

asmとcは文法は違うが近い、逆にcとc++は文法は似てるが全く別物。
0064ビル・ジョブスNGNG
>>59
うー・・・現実ははかなり違うぞ・・・今でもROM64KB・RAM16KBなんて環境も
あるからな。
そこで、リアルタイムマルチタスクOS(ビル・ジョブス作)使ってる製品も
多いからな・・・
でも、最近はSH4だからGUIまで作っちまったよ。
0065デフォルトの名無しさんNGNG
>>64
ディスプレイがないのに・・・。

「0x0010000から1KBはボクちん専用VRAM〜♪」

かわいそうな人だ。
0066デフォルトの名無しさんNGNG
>>64
そんな小さな環境でどんなスケジューリングをやってたんですか?
0067デフォルトの名無しさんNGNG
>>64
( ゚д゚)ポカーン
0068ビル・ジョブスNGNG
>>65
おまえなーSH4クラスの製品ならLCDくらい付いてる事を想像できないか?

この言葉、おまえに返すよ、
>かわいそうな人だ。
0069デフォルトの名無しさんNGNG
( ゚Д゚ )ポカーン
0070デフォルトの名無しさんNGNG
>>68
2行16文字のLCD上でGUI・・・かわいそうな人だ。
0071デフォルトの名無しさんNGNG
>>68
是非ともLCD付きのLSIチップを見せてください!
0072デフォルトの名無しさんNGNG
ビル・ジョブスは叩かれる伽羅なんですか?
0073デフォルトの名無しさんNGNG
>>72
そうです。
このスレはビルに混じれ酢付けるアフォを見物するスレなんです。
0074デフォルトの名無しさんNGNG
コテハンを叩くスレはここですか。
情けない。
0075ビル・ジョブスNGNG
>>66
15レベルプライオリティー15、リスケジューリングタイム1ms、カーネルコード8KB、
TCB(タスクコントロールブロック)のRAM容量は実装依存。
もちろん各プライオリティーキューはラウンドロビン。
処理内容はLCD制御、キースイッチ制御、ネットワーク制御、ETC.。
ですが、なにか?
0076デフォルトの名無しさんNGNG
>>72
いや、技術はあるから叩いてもいいんです
それを跳ね返すだけの実力がある。
0077デフォルトの名無しさんNGNG
みんな食い付き良すぎだYO!!
ビル・ジョブスってのは、厨房のフリしてストレス発散したくなった時に使う
共有コテハンなんだからさぁ。
と言ってみるテスト。
0078デフォルトの名無しさんNGNG
>それを跳ね返すだけの実力がある。
プ
0079デフォルトの名無しさんNGNG
>>75
ありがと
0080デフォルトの名無しさんNGNG
>>77
正解
0081デフォルトの名無しさんNGNG
・・・
0082ビル・ジョブスNGNG
こんなカンジのソースコード書いてますが、貴様らに理解できますか?

typedef struct TCB {
UCHAR id; /* My task ID */
UCHAR pid; /* Parent task ID */
UCHAR prior; /* Task Priority */
UCHAR cond; /* Task condition */
REGS *rg; /* Registers */
int wait; /* Sleep time (1ms*n) */
void *handle; /* Waiting msg/event/semaphore handle*/
int ewmode; /* Waiting event mode */
DWORD emask; /* Waiting event mask */
DWORD cputime; /* Used CPU time */
void *isp; /* Initial stack pointer */
struct TCB *prev,*next; /* Previous/Next TCB ptr */
} TCB;

typedef struct QUEUE {
TCB *head, *tail;
} QUEUE;

QUEUE ReadyQ[SYS_PRIORITY_MAX], SleepQ;

void add_ready_queue_head(TCB *t)
{
QUEUE *q = &ReadyQ[t->prior];
t->prev = NULL;
if (!(t->next = q->head))
q->head = q->tail = t;
else
q->head = q->head->prev = t;
}

void add_ready_queue_tail(TCB *t)
{
QUEUE *q = &ReadyQ[t->prior];
t->next = NULL;
if (!(t->prev = q->tail))
q->head = q->tail = t;
else
q->tail = q->tail->next = t;
}
0083デフォルトの名無しさんNGNG
お前がスゴイ!のはわかったって。
0084デフォルトの名無しさんNGNG
ビル・ジョイスはWin使いかよ。萎え〜
82のようなコードは生理的に受け付けない
0085デフォルトの名無しさんNGNG
さっきの環境から言ったら、pidとppidで1バイトで良さそうに
思うのですがどうでしょうか?>ビルさん
0086デフォルトの名無しさんNGNG
ビルは適当に検索して、それらしい単語やコードをコピペしてるだけだろ。
深いところに突っ込むと、ろくに答えないで煽り返してごまかすし。
0087デフォルトの名無しさんNGNG
笑いが止まらぬどころか鼻血がとまんねーよ、オイ
0088デフォルトの名無しさんNGNG
うわぁ、さすがビル・ジョブスさん。さすがです。
0089デフォルトの名無しさんNGNG
TCB制御にint直打ちやNULLマクロつかッてんの初めて見た。
突っ込むときりがないんで、とりあえず、その心意気だけは買って褒め称えるスレにでもするか。
0090祭りだワッショイ!NGNG
真スレ勃ったばっかなのに波乱の予感・・・
0091デフォルトの名無しさんNGNG
ここは、ビルへのツッコミで1000を目指すスレになりました。
0092ビル・ジョブスNGNG
>>85
idとpid・・・で1バイト?ってことは4ビットで15タスク・・・は無理でしょ。
というか拡張性無さ過ぎないか?ETC.の処理もあるし。

>>86、>>87
おーおまえらよくもそこまで言ってくれたな・・・
まーいーや時間の無駄だから。
0093デフォルトの名無しさんNGNG
教科書通りのコード見せられてもなあ。
タスク制御なんてそこらのオタゲーPGでも書けるンだっつーの。
応用コードミセロヤ。
0094執行部NGNG
所詮ビルに故・日下部の代わりは無理か。
次はちゃんとしたのを送るとしよう。
0095デフォルトの名無しさんNGNG
>>94
次の刺客は林あたりをよろしく。
0096デフォルトの名無しさんNGNG
せめてエスピーテーメー級の骨太のやつ頼むぜ。
0097デフォルトの名無しさんNGNG
オイオイサガッテルヨ
ビルサンサイコー
0098デフォルトの名無しさんNGNG
TCB構造体には無駄があると思います。みなさんもそう思いますよね?
ビルさんの出してくれたデータ構造体の叩き台を再検討しましょう!
まずはそれから!!!次に処理。
0099ビル・ジョブスNGNG
>>93
うーん・・・応用って言われてもなー・・・

こんなのでどう?おれの作ったメモリアロケーション(MMUなしバージョン)
だけど、文句しか言えないカワイソーナ貴様には3年がんばっても理解不可能だと
思うけど・・・

typedef struct MCB {
WORD check;
USHORT owner;
DWORD size;
struct MCB *prev,*next;
} MCB;

void *far_malloc(MCB **mh, MCB **mt, void *area, int area_max, int size)
{
MCB *m;
size = (size + (sizeof(int) - 1)) & ~(sizeof(int) - 1);
if (*mt && (size > area_max ||
(DWORD)(*mt)+((*mt)->size+sizeof(MCB)+size) >= (DWORD)(area)+area_max))
return (void*)NULL;
if (!*mh) {
*mh = (MCB*)area;
(*mh)->check = MCB_CHECK_CODE;
(*mh)->owner = Running->id;
(*mh)->size = size + sizeof(MCB);
(*mh)->prev = (*mh)->next = NULL;
*mt = *mh;
return (void*)((DWORD)(*mh)+sizeof(MCB));
}
m = (MCB*)((DWORD)(*mt)+(*mt)->size);
m->check = MCB_CHECK_CODE;
m->owner = Running->id;
m->size = size + sizeof(MCB);
m->prev = *mt;
m->next = NULL;
*mt = (*mt)->next = m;
return (MSG*)((DWORD)(m)+sizeof(MCB));
}
0100ビル・ジョブスNGNG
int far_mfree(MCB **mh, MCB **mt, void *p)
{
MCB *m;
p = (void*)((DWORD)(p)-sizeof(MCB));
if (!*mh || ((MCB*)p)->check != MCB_CHECK_CODE) return NG;
((MCB*)p)->check = 0;
if (*mh == (MCB*)p) {
if (!(*mh = (*mh)->next)) *mt = NULL;
else (*mh)->prev = NULL;
return OK;
}
if (*mt == (MCB*)p) {
*mt = (*mt)->prev;
(*mt)->next = NULL;
return OK;
}
for (m = (*mh)->next; m; m = m->next) {
if (m == (MCB*)p) {
m->prev->next = m->next;
m->next->prev = m->prev;
break;
}
}
return OK;
}
0101デフォルトの名無しさんNGNG
>>99
素朴な疑問。普段からコメントは書かずにやってるの?
■ このスレッドは過去ログ倉庫に格納されています