スポンサーリンク

このドキュメントの内容は、以下の通りです。

Unixのプログラムでは、処理中にシグナルを受信した場合に、シグナル受信前に行っていた処理をやめて、ほかのことをするプログラムを書くときなどに、setjmpとlongjmpを利用することがあります。
想定した時間を超えた場合に処理をやめるときなどにも利用できます。
ある意味 goto 文みたいなものなので、多用すると訳が分からなくなるので利用には注意が必要です。

サンプルコード


早速、サンプルコードです。

このプログラムは、alarm()でシグナルを発生されます。
シグナルが発生すると timeout() が呼び出されるようになっています。

まず、setjmp()で戻るべき場所を決めます。
alarm()を呼び出し、sleep()でプログラムが眠ります。
sleep()で寝ていある間に、alarm()によって、timeout()が呼び出されます。
timeout()では、特に何も処理は行わず、longjmp() で setjmp() したところに戻り、別の処理をします。

というのを for文で繰り返すプログラムです。
alarm()は、必ず、sleep()が完了する前に、アラームを発生させます。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

#include <signal.h>
#include <setjmp.h>

jmp_buf jmp;

void
timeout ( int no ) {
	longjmp ( jmp, 1 );
}

int
main (int argc, char *argv[])
{
	int	i = 0;

	for (i = 0; i < 3; ++i) {
		int t = setjmp ( jmp );
		if ( 0 == t ) {
			signal ( SIGALRM, timeout );
			printf ("Sleep\n");
			alarm (1);
			sleep(2);
			alarm (0);
		} else {
			signal ( SIGALRM, SIG_DFL );
			alarm (0);
			printf ("Timeout\n");
		}
	}

	exit (EXIT_SUCCESS);
}

コンパイル


gcc jmp.c

実行例


実行すると以下の結果になるはずです。

./a.out
Sleep
Timeout
Sleep
Timeout
Sleep
Timeout

実行環境について


このサンプルコードは、FreeBSDとMacOS Xでは動作しました。
しかしながら、Linuxでは、期待した動作をしません。
2回目からのalarm()が発行されず、1度目のalarm()え設定したときにしかtimeout()が呼び出されませんでした。

Linuxの場合には、sigsetjmp/siglongjmpを利用することで、問題は解決できます。

スポンサーリンク
スポンサーリンク
 
いつもシェア、ありがとうございます!


もっと情報を探しませんか?

関連記事

最近の記事

人気のページ

スポンサーリンク
 

過去ログ

2020 : 01 02 03 04 05 06 07 08 09 10 11 12
2019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12

サイト

Vim入門

C言語入門

C++入門

JavaScript/Node.js入門

Python入門

FreeBSD入門

Ubuntu入門

セキュリティ入門

パソコン自作入門

ブログ

トップ


プライバシーポリシー