OLTPにつける薬はあるのか?
- log file sync の進化と謎 Insight Technology, Inc.
JPOUG (Japan Oracle User Group)
新久保 浩二 (@kouji_s_0808)

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.
Who am I ?

1.

データベース マニアック担当

2.

Oracle ACE

3.

JPOUG(Japan Oracle User Group)
(http://www.jpoug.org)

本資料に使用されている社名、ロゴ、製品、サービス名およびブランド名
は、該当する各社の登録商標または商標です。本資料の一部あるいは全体
について、許可なく複製および転載することを禁じます。
本資料の内容に関して、不適当な表現や検証が足りない部分もありますが
ご容赦ください。

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

2
こ

み

っ

と

COMMIT
用途
COMMIT文を使用すると、現行のトランザクションを終了し、トランザクションで
実行したすべての変更を確定できます。トランザクションとは、Oracle Databaseが
1つの単位として扱う一連のSQL文です。
また、この文によって、トランザクション内のセーブポイントがすべて消去され、
トランザクション・ロックが解除されます。
Database SQL言語リファレンスより

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

3
本日の試み
本日は、日頃皆さんが何気なく実行するcommitを肴に、
「commitする人の気持ち」 と
「commitされる人の気持ち」

を堪能しようという試みです。
- commitの裏舞台では、どんな事がくりひろげられてるの?

- Oracleリリースが進んで、 commit関連の何かが変わったの?
- 11gでは?
- 12cでは?

- 深まる謎?
とか (ちなみに、本資料の環境は主にLinux上でのお話です。)
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

4
OLTP系ベンチマークでよく見る風景

Commit クラス

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

5
具体的にはlog file sync

log file sync

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

6
いざ!!

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

7
今日の大事な点 その1 (プロセスの関係)
$ ps -ef | grep sqlplus | grep –v grep
oracle
31699 31645 0 07:55 pts/1
00:00:00 sqlplus

as sysdba

$ pstree -alp 31699
フォアグランド
sqlplus,31699 ¥040 as sysdba
│
└─ oracle,32567 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))

$ ps -ef | grep lgwr | grep –v grep
oracle
31595
1 0 Nov02 ?

SHADOWプロセス
(commitする人)
00:22:16 ora_lgwr_oracle11g

今日は、この人たちの
system callを追いかけます。
(latch等は追いかけません)

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

LGWR
(commitされる人)

8
今日の大事な点 その2 (セマフォ)
SEMCTL(2)
名前

書式

Linux Programmer’s Manual
SEMOP(2)

SEMOP(2)

semctl - セマフォの制御操作を行なう
名前
semop, semtimedop - セマフォの操作
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

書式

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
int semop(int semid, struct sembuf *sops, unsigned nsops);

semctl(2)
他のプロセスを起こす

説明

SEMCTL(2)
Linux Programmer’s Manual

semtimedop(2)
他のプロセスに起こされ
るまで寝る
またはセマフォ集合の

semctl() は、 semid で指定されたセマフォ集合 (semaphore struct sembuf *sops, unsigned nsops,
int semtimedop(int semid, set)
semnun 番目のセマフォに対して、 cmd で指定された制御操作を行なう (集合内のセマフ ォ
struct timespec *timeout);
の番号は 0 から始まる)。
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
この関数は、 cmd の値に依存して、3 個または 4 個の引き数を持つ。引き数が 4 個の場合
、第 4 引き数の型は union semun semtimedop(): _GNU_SOURCE
である。呼び出し元プログラムは、この共用体 (union)
を以下のように定義しなければならない。
説明
union semun {
セマフォ集合 (semaphore set) のメンバーの各セマフォは以下の関連情報を持っている:
int
val;
/* SETVAL の値 */
struct semid_ds *buf;
/* unsigned short semval; /* セマフォ値 */
IPC_STAT, IPC_SET 用のバッファ */
unsigned short *array; /* unsigned SETALL 用の配列 *//* ゼロを待つプロセス数 */
GETALL, short semzcnt;
struct seminfo *__buf; /* unsigned short semncnt; /* 増加を待つプロセス数 */
IPC_INFO 用のバッファ
(Linux
pid_t 固有) */ sempid; /* 最後に操作を行なったプロセス */
};
semop() は semid で指定されたセマフォ集合の選択されたセマフォに対して操作を行う。

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

9
一般的なcommit (11.2.0.4)
皆さんご存知のcommitの動作
SHADOW PROCESS
LGWR
------------------------------------------------------------------------------ -----------------------------------------------------------------15:56:52.451519
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) = -1 EAGAIN
15:56:55.452866
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) = -1 EAGAIN
15:56:58.454356
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) =
15:57:01.125824 update !
15:57:01.129724 update complete
15:57:01.181562 commit !
15:57:01.184351 semctl(1802252, 18, SETVAL, 0x1) = 0
15:57:01.184939
io_submit(140400303636480, 2, {{0x7fb17c6a1480, 0, 1, 0, 267}, …}) = 2
15:57:01.185218 semtimedop(1802252, {{34, -1, 0}}, 1, {0, 100000000}) =
15:57:01.185558
io_getevents(140400303636480, 2, 128, {{0x7fb17c6a1480,…,{0,0}) = 2
15:57:01.185729
semctl(1802252, 34, SETVAL, 0x1) = 0
15:57:01.186277
semtimedop(1802252, {{18, -1, 0}}, 1, {0, 270000000}) = -1 EAGAIN
15:57:01.186385 commit complete
15:57:01.457908
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0} =

Shadow process

LGWR process

多分、log file sync
は shadowプロセスが
2789μ秒
semtimedop(2)で
commit
眠ってから、LGWRに
起こされて、commit
完了を内部的に確認
できるまで

log file sync

semtimedop

semctl

656 μ秒

io_getevents

io_submit

588 μ秒

619 μ秒 171 μ秒

commit
complete

semctl

semtimedop

log file parallel write

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

10
深まる謎 その1
プロセスの復帰に関して、OSのプロセス・スケジューラーの影響はあるのか?
log file sync
Shadow process
2789μ秒
commit

semtimedop

semctl

656 μ秒

io_getevents

io_submit

commit
complete

semctl

LGWR process

588 μ秒

619 μ秒 171 μ秒

semtimedop

log file parallel write

もし、影響があるとしたら、Linuxのタイマー割り込み分解性能ってHZ依存Tickで
1msとか4msとか10msとかじゃなかった?
そうなると、環境によっては、残念なこともあるかもしれない?

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

11
深まる謎 その1 の考察
まず、RHEL5.6 (2.6.18-238.el5) と OEL6.4(2.6.39-400.209.1.el6uek.x86_64)
で、nanosleep(2)で10回、1μ秒スリープしてみてOSのプロセス・スケジューラーによる遅延を
確認してみる。
最近のOS(検証環境はOracle Linux 6.4 - UEK) だとTicklessカーネル&高精度
タイマーになっていて、昔みたいにHZ依存のTickで世界が縛られることはなくなっているよう。
OS別割り込み分解性能
2.6.39-400.209.1.el6uek.x86_64
3,000

1971

1994

2007

55

2005

2.6.18.238.el5-x86_64

55

2000

1986

2144

1860

1993

μ秒

2,000
1,000

56

55

55

54

61

55

54

0

#1

#2

#3

#4

#5

#6

#7

#8

#9

これだと、OSのバージョンで、相当OLTP性能へ影響が出てしまうはずだが、本当なのか?

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

12
深まる謎 その1 の考察
ということで、簡単なセマフォのサンプルで試してみた。
セマフォでのWakeup時間の実測値
2.6.39-400.209.1.el6uek.x86_64

μ秒

200

2.6.18.238.el5-x86_64

185

100

93
58

61
46

89

81
53

60

45

131
106
66
45

60
45

57
48

0
#1

#2

#3

#4

#5

#6

#7

#8

#9

正確にカーネルのソースは見てないですが、nanosleep(2)の場合はOSのプロセス・スケジュー
ラーがタスク状態を変更して、セマフォ関連は、OSのプロセス・スケジューラーに非依存で実装
されている模様(ここ、大事)

なので、セマフォを使ってcommitの状態のやり取りを行っている限り、OS
のプロセス・スケジューラーの遅延は、そんなに気にならないくらい高速。
(でも遅延 - log file sync - は無くならない)
Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

13
余談

余談

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

14
(余談) commitする人にも事情はあるので
皆さんご存知のcommitのモードは大きく4つ
commitのモードは[IMMEDIATE] と BATCH
commitの待機モードは[WAIT] と NOWAIT
初期パラメーターで指定するなら
10gの頃は
COMMIT_WRITE=“IMMEDIATE,WAIT” とか
11g以降は
COMMIT_LOGGING=IMMEDIATE
COMMIT_WAIT=WAIT とか
SQL単位で指定するなら
commit write immediate wait; とか

皆さんご存知のPL/SQLのcommitのデフォルトモードはBATCH NOWAIT
❝ データベース初期化パラメータCOMMIT_LOGGINGおよびCOMMIT_WAITが
設定されていない場合、非分散トランザクションに対するPL/SQLのデフォルトの
コミット動作はBATCH NOWAITです。❞
PL/SQL言語リファレンス より

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

15
(余談) commitモードによる違い (11.2.0.4)
PL/SQL で commit のモードを変えながら、100回update + commitを実行

PL/SQL immediate wait
% time

seconds

7.50
0.37

usec/call

calls

errors

syscall

0.000472 5

100

0

semtimedop

0.000023 0

100

0

semctl

PL/SQL batch wait

% time

seconds

usec/call

calls

errors

syscall

0.00

0.00000

0

100

0

semtimedop

0.00

0.00000

0

100

0

semctl

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

16
(余談) commitモードによる違い (11.2.0.4)
PL/SQL immediate nowait
% time seconds usec/call
このケースだとPL/SQLで実行してい
るので(多分)PL/SQLブロックの抜け
0.39
0.000023 0
る際に、semctl(2)でLGWRを起こ
0.00
0.000000 0
して、semtimedop(2)でlog
bufferのフラッシュ完了を待っている。
PL/SQL batch nowait
普通のSQLだと、semtimedop(2)
% time seconds usec/call
は実行されない。つまり、REDOログ
0.00
0.000000 0
への書き込みの正常性を全くチェック
0.00 しませんので、ご注意を!
0.000000 0
さらに、semtimedop(2)で待たない
PL/SQL ので当然log file syncも(ほぼ)ない
commit (DEFAULT)
% time Seconds usec/call
です。

calls

errors

syscall

100

0

semctl

1

0

semtimedop

calls

errors

syscall

2

0

semctl

1

0

semtimedop

calls

errors

syscall

0.00

0.000000 0

100

0

semctl

0.00

0.000000 0

1

0

semtimedop

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

17
(余談) commitモードでの速度比較
ご参考までに
commit mode comparison (11.2.0.4)
90
80

76.921

75.878

Elapsed Time (sec)

70
60
50

40
30
20

12.395

10.832

11.739

PL/SQL IMMEDIATE

PL/SQL BATCH NOWAIT

PL/SQL COMMIT

10
0
PL/SQL IMMEDIATE
WAIT

PL/SQL BATCH WAIT

NOWAIT

(DEFAULT)

100,000 commits per every insert

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

18
新種のcommit発見! (11.2.0.x)

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

19
新種のcommit発見! (11.2.0.4)
(少なくとも私は知らなかった)新種のcommitが出てきました!
SHADOW PROCESS
LGWR
------------------------------------------------------------------------------ -----------------------------------------------------------------12:04:11.936399
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) = -1 EAGAIN
12:04:14.940066
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) =
12:04:16.385834 update !
semtimedop(2)
12:04:16.388814 update complete
semctl(2)で他の
で眠るかわりに
12:04:16.388954 commit !
プロセスを起こす。
nanosleep(2)
12:04:16.601262 semctl(1802252, 18, SETVAL, 0x1) = 0
ということはしない
で眠っている
12:04:16.601762 nanosleep({0, 466000}, 0x7fff24c2dc80) = 0
12:04:16.602330
io_submit(140400303636480, 2, {{…}}) = 2
12:04:16.602380 nanosleep({0, 466000}, 0x7fff24c2dc80) = 0
12:04:16.602995 nanosleep({0, 466000}, 0x7fff24c2dc80) = 0
12:04:16.603163
io_getevents(140400303636480, 2, 128,…,{0,0}) = 2
12:04:16.603724
semtimedop(1802252, {{18, -1, 0}}, 1, {1, 340000000}) = -1 EAGAIN
12:04:16.604007 commit complete
12:04:17.945345
semtimedop(1802252, {{18, -1, 0}}, 1, {3, 0}) = -1 EAGAIN

log file sync
Shadow process
312.308ミリ秒
commit

500 μ秒

618 μ秒

semctl

615 μ秒
nanosleep

1012 μ秒
commit
complete

io_getevents

io_submit

semtimedop

LGWR process
1068 μ秒

833 μ秒

561 μ秒

log file parallel write

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

20
post/wait と post/polling (11.2.0.x)
11gR2から初期化パラメーター “_use_adaptive_log_file_sync” デフォルトFALSEが
登場しました。
あまり詳細ではないですが、以下に情報があります。
MOS 1541136.1
Waits for "log file sync" with Adaptive Polling vs Post/Wait Choice Enabled

ちなみに11.2.0.3からは、デフォルト TRUEになってました。
パラメーターの名前から分かるとおり、log file sync (つまり、shadow プロセスが、LGWRが
行う、REDOログへの書き込み完了通知を待っている) に関して、

- post/wait (セマフォを使ってLGWRがshadowプロセスにREDOログ書き込み完了を通知)
- post/polling (shadowプロセスがsleepにより自身でREDOログ書き込み完了を確認)
の2つの方式を動的に変更するといった機能です。

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

21
深まる謎 その2
で、誰が、どんな理由で、お得なんでしょうか?
post/wait

log file sync

Shadow process
2789μ秒
commit

semtimedop

semctl

656 μ秒

io_getevents

io_submit

commit
complete

semctl

LGWR process

588 μ秒

619 μ秒 171 μ秒

post/polling

semtimedop

log file sync

Shadow process
312.308ミリ秒
commit

500 μ秒

618 μ秒

semctl

615 μ秒
nanosleep

io_getevents

io_submit

1012 μ秒
commit
complete
semtimedop

LGWR process
1068 μ秒

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

833 μ秒

561 μ秒

22
深まる謎 その2 の考察
LGWRは喜ぶ

post/poll

大量のセッションが大量の
commitを同時多発的に
実行した際、
post/wait方式であれば、
LGWRは全てのcommit
要求元にsemctl(2)で通
知する必要がある。

log file syncは増える可
能性もある?

従来のpost/waitは
LGWRから通知されていた
ので、可能な限り即時に
commit完了通知を受け
取ることができた。
しかし、post/pollingでは
nanosleep(2)(このテスト
時は466μ秒だったが、実
際は動的に決定されると思
う)でスリープするので、無駄
に寝てしまって、 commit
のレイテンシーが悪化する
可能性があると思われる。

このsemctl(2)による通知
が忙しくて、本来の仕事の
online REDOログへフラッ
シュが怠けがちなっているシ
ステムでは、post/polling
によるsemctl(2)からの解
放は有効かもしれない。

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

23
ん!? (12.1.0.1)

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

24
ん!?なパターンも出てきた (12.1.0.1)
LGWRは新種のLG00(LGWR Worker)へ“左から右に受け流している”
SHADOW PROCESS
LGWR
----------------------------------------------- ---------------------------------------------------18:29:18.575401
semtimedop(622604, {{19,…}}, 1, {3, 0}) = -1 EAGAIN
18:29:21.577337
semtimedop(622604, {{19,…}}, 1, {3, 0}) = -1 EAGAIN
18:29:21.963171
18:29:24.579259
semtimedop(622604, {{19,…}}, 1, {3, 0}) =
18:29:24.964188
18:29:25.658472 update !
18:29:25.661777 update complete
18:29:25.662136 commit !
18:29:25.677012 semctl(622604, 19, SETVAL,…) = 0
18:29:25.677411
semctl(622604, 21, SETVAL, 0x7fff00000001) = 0
18:29:25.677655
semtimedop(622604, {{19,…}}, 1, {1, 910000000}) =
18:29:25.677772
18:29:25.677838 semtimedop(622604, {{33,…}},…) =
18:29:25.678392
18:29:25.678967
18:29:25.679130
18:29:25.679370
18:29:25.679676 commit complete
18:29:27.580963
semtimedop(622604, {{19,…}}, 1, {3, 0}) = -1 EAGAIN

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

LG00
----------------------------------------------------

semtimedop(622604, {{21,…}}, 1, {3,0}) = -1 EAGAIN
semtimedop(622604, {{21,…}}, 1, {3,0}) =

io_submit(139749499707392, 2, {{…}}) = 2
io_getevents(139749499707392, 2, 128,…,{0,0}) = 2
semctl(622604, 33, SETVAL, 0x7fff00000001) = 0
semctl(622604, 19, SETVAL, 0x7fff00000001) = 0
semtimedop(622604, {{19,…}},…) =

25
新種のプロセス LGnn (12.1.0.1)

12cR1から初期化パラメーター “_use_single_log_writer” デフォルトADAPTIVEが登場
している。どうやら、Scalable Log Writerとも呼ばれるらしい。
詳細不明ですが、新種のプロセスLGnn(Log Writer Workerプロセス)がデフォルトで2つ起動
され、状況により、複数のWorkerプロセスに、I/Oを任せることで、REDOログへの書き込み
スループットを向上させようとしていると考えられる。
ちなみに、LGnnのプロセス数は”_max_outstanding_log_writes”で制御されている模様
“_use_single_log_writer”の設定として
- TRUE
常にシングル(LGWR)がREDOログへの書き込みを担う。従来の動作
- FALSE
常に一旦LGWRが要求を受けて、LGnnがREDOログへ書き込む。
- ADAPTIVE きっと、両者を動的に切り替える

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

26
深まる謎 その3
Scalable Log Writer

log file sync

Shadow process
commit

semctl

semtimedop

commit
complete

LGWR process

semctl

semtimedop

LG00 process

io_submit

io_getevents

semctl

semctl

正直、ADAPTIVE状態では、なかなか、Workerプロセスを使うモードに移行してくれなかった。
さらに、強制的にWorkerプロセスを使うモード(先ほどのスライドの例)だと、プロセス間通信に
よる遅延が増え、全体的なcommitレスポンスは悪化していた。(そういうパターンもあった)
Scalable Log Writerの力はこんなものではないはずなので、今後、要検証。

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

27
と言うことで
なじみ深いcommitという動作一つでも、奥は深い。
データベースでは、非常にベーシックなアーキテクチャでも、時代と共に変化していきている。
ただ、その機能やアーキテクチャの変更が、現在のシステムに有効かどうかは、現時点
では、ちゃんと見極める必要がある。 (過度に憶病になる必要はないと思いますが)
ただ、流行りのAdaptiveといった説明にならない説明は個人的には嫌いです。
なので、常識の範囲で、中身を見てみると、その機能の気持ちも分かるようになるし、
得意、不得意な点も見えてくるので、個人的にはおススメ。
(ただ、本番環境では絶対にやらないでくださいね。)
最後に、データベースのパフォーマンス問題は奥が深いので、一言で解決可能な魔法の薬は
存在しません。現象を理解し、深く解析し、データベースやそのプロセスの気持ちになって考え
てあげる事が大切です。

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

28
ORA-3113

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

29
Appendix: tick_test.c
#include
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<time.h>
<sys/time.h>
<unistd.h>

int LOOP = 10;

int main (int argc, char **argv)
{
struct timeval tv[LOOP];
struct timespec req;
int i;
req.tv_sec = 0;
req.tv_nsec = 1000; // 1us
for (i = 0; i < LOOP; i++) {
nanosleep(&req, NULL);
gettimeofday(tv + i, NULL);
}
for (i = 0; i < LOOP; i++)
printf("%ld:%06ld¥n", (long)tv[i].tv_sec, (long)tv[i].tv_usec);
return 0;
}

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

30
Appendix: seminit.c
#include
#include
#include
#include

<sys/types.h>
<sys/ipc.h>
<sys/sem.h>
<stdio.h>

#define KEY (1492)
int main()
{
int id;
union semun {
int val;
struct semid_ds *buf;
ushort * array;
} argument;
argument.val = 0;
id = semget(KEY, 1, 0666 | IPC_CREAT);
if(id < 0)
{
fprintf(stderr, "Unable to obtain semaphore.¥n");
return 0;
}
if( semctl(id, 0, SETVAL, argument) < 0)
{
fprintf( stderr, "Cannot set semaphore value.¥n");
}
else
{
fprintf(stderr, "Semaphore %d initialized.¥n", KEY);
}
}

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

31
Appendix: sem_wakeup.c
#include
#include
#include
#include

<stdio.h>
<sys/types.h>
<sys/ipc.h>
<sys/sem.h>

#define KEY (1492)
int main()
{
int id;
int retval;
struct timeval tv;
id = semget(KEY, 1, 0666);
if(id < 0)
{
fprintf(stderr, "Program cannot find semaphore, exiting.¥n");
return 0;
}
printf("Program about to do a V-operation. ¥n");
gettimeofday(&tv, NULL);
printf("%ld:%06ld¥n", (long)tv.tv_sec, (long)tv.tv_usec);
retval = semctl(id, 0, SETVAL, 1);
if(retval == 0)
{
printf("Successful V-operation by program sem_wakeup.¥n");
}
else
{
printf("sem_wait: V-operation did not succeed.¥n");
perror("REASON");
}
}

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

32
Appendix: sem_wait.c
#include
#include
#include
#include
#include
#include
#include
#include

<stdio.h>
<sys/types.h>
<sys/ipc.h>
<sys/sem.h>
<stdlib.h>
<time.h>
<sys/time.h>
<unistd.h>

gettimeofday(&tv, NULL);
printf("%ld:%06ld¥n", (long)tv.tv_sec, (long)tv.tv_usec);
retval = semtimedop(id, operations, 1, &req);
gettimeofday(&tv, NULL);
printf("%ld:%06ld¥n", (long)tv.tv_sec, (long)tv.tv_usec);

#define KEY (1492)

if(retval == 0)
{
printf("Successful P-operation by program sem_wait.¥n");
printf("Process id is %d¥n", getpid());
}
else
{
printf("sem_wait: P-operation did not succeed.¥n");
}

int main()
{
int id;
struct sembuf operations[1];
int retval;
struct timeval tv;
struct timespec req;
}
req.tv_sec = 10;
req.tv_nsec = 0;
id = semget(KEY, 1, 0666);
if(id < 0)
{
fprintf(stderr, "Program cannot find semaphore, exiting.¥n");
return 0;
}
printf("Program about to do a P-operation. ¥n");
printf("Process id is %d¥n", getpid());
operations[0].sem_num = 0;
operations[0].sem_op = -1;
operations[0].sem_flg = 0;

Copyright © 2013 Insight Technology, Inc. All Rights Reserved.

33

Dbts2013 特濃jpoug log_file_sync