makecontext - ライブラリコールの説明 - Linux コマンド集 一覧表
- 名前
- 書式
- 説明
- 返り値
- エラー
- 注意
- 準拠
- 例
- 関連項目
名前
makecontext, swapcontext - ユーザコンテキストを操作する
書式
#include <ucontext.h>
void makecontext(ucontext_t *
ucp
, void *
func
(),
int
argc
, ...);
int swapcontext(ucontext_t *
oucp
, ucontext_t *
ucp
);
説明
System V 的な環境では、
mcontext_t
および ucontext_t
という 2 つの型と、
getcontext
(), setcontext
(),
makecontext
(), swapcontext
()
という 4 つの関数が
<ucontext.h>
で定義されており、あるプロセス内部で制御下にある複数のスレッド間で、
ユーザレベルのコンテキスト切替えができるようになっている。
これらの型と、最初の 2 つの関数については、
getcontext
(2) を参照のこと。
makecontext
() 関数は、ポインタ ucp
が指すコンテキストを変更する
(ucp
は以前の getcontext
() 呼び出しで得られたものである)。
makecontext
() を起動する前には、呼び出し者は、このコンテキスト用に
新しいスタックを確保し、そのアドレスを ucp->uc_stack
に代入し、
さらに後継のコンテキストを定義し、そのアドレスを ucp->uc_link
に
代入しなければならない。
このコンテキストが将来
(setcontext
() または swapcontext
() によって)
有効にされると、関数 func
が呼ばれ、
引き数として
argc
以降の整数
(
int
)引き数の列が渡される。
呼び出し者は
argc
にこれらの引き数の個数を指定しなければならない。
この関数が戻ると、後継のコンテキストが有効になる。
後継コンテキストのポインタが NULL の場合、そのスレッドが終了する。
swapcontext
() 関数は現在のコンテキストを
ポインタ oucp
が指す構造体に保存し、
ポインタ ucp
が指すコンテキストを有効にする。
返り値
成功すると、swapcontext
() は返らない
(しかし後に oucp
が有効になった場合には返ることがある。
このときには swapcontext
() は 0 を返すように見える。)
失敗すると、swapcontext
() は -1 を返し、
errno
をエラーに応じて設定する。
エラー
-
ENOMEM
-
スタックに割り当てる空間が残っていない。
注意
ucp->uc_stack
の解釈は
sigaltstack
(2) の場合と同じである。
すなわちこの構造体には、
スタックとして用いられるメモリ領域の開始アドレスと長さが含まれ、
これはスタックが伸びる方向がどちらであるかには関係しない。
したがって、ユーザプログラムはこの件については心配しなくてよい。
準拠
例
以下のサンプル・プログラムは、
getcontext
(),
makecontext
(),
swapcontext
().の使用方法の例を示すものである。
このプログラムを実行すると、以下のような出力が得られる:
$ ./a.out
main: swapcontext(&uctx_main, &uctx_func2)
func2: started
func2: swapcontext(&uctx_func2, &uctx_func1)
func1: started
func1: swapcontext(&uctx_func1, &uctx_func2)
func2: returning
func1: returning
main: exiting
#include <ucontext.h>
#include <stdio.h>
#include <stdlib.h>
static ucontext_t uctx_main, uctx_func1, uctx_func2;
#define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
static void
func1(void)
{
printf("func1: started\n");
printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n");
if (swapcontext(&uctx_func1, &uctx_func2) == -1)
die("swapcontext");
printf("func1: returning\n");
}
static void
func2(void)
{
printf("func2: started\n");
printf("func2: swapcontext(&uctx_func2, &uctx_func1)\n");
if (swapcontext(&uctx_func2, &uctx_func1) == -1)
die("swapcontext");
printf("func2: returning\n");
}
int
main(int argc, char *argv[])
{
char func1_stack[16384];
char func2_stack[16384];
if (getcontext(&uctx_func1) == -1)
die("getcontext");
uctx_func1.uc_stack.ss_sp = func1_stack;
uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
uctx_func1.uc_link = &uctx_main;
makecontext(&uctx_func1, func1, 0);
if (getcontext(&uctx_func2) == -1)
die("getcontext");
uctx_func2.uc_stack.ss_sp = func2_stack;
uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
/* Successor context is f1(), unless argc > 1 */
uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
makecontext(&uctx_func2, func2, 0);
printf("main: swapcontext(&uctx_main, &uctx_func2)\n");
if (swapcontext(&uctx_main, &uctx_func2) == -1)
die("swapcontext");
printf("main: exiting\n");
exit(EXIT_SUCCESS);
}
関連項目
- Linux Tips 関連記事
- Linux Tips(目次)
- Linux ディストリビューション一覧
- rpm のファイル名にあるi386とかi686とは
- 自分のマシンの情報を調べる
- cron の設定
- ssh の root ログインを禁止する
- ssh を、ユーザ、IPでアクセス制限
- 鍵交換方式によるssh接続
- 鍵交換方式によるssh接続( windowsから )
- 複数ファイル内の文字列を置換して上書き保存する
- あるグループをイニシャルグループとするユーザー一覧出力
- 複数ファイルのファイル名を一括変換する
- 連番ファイルをコマンド一発で作成する
- 中身がランダムなファイルを任意のサイズで作成する
- Linux ユーザーアカウントをロック・アンロックする