longjmp可以多次调用重入的。但是是否支持在不同的线程间切换呢。。。测试一番
Windows 下肯定是不支持的,下面代码一跑就挂
#include "StdAfx.h"
#include <iostream>
#include <setjmp.h>
#include <Windows.h>
jmp_buf buf;
DWORD id;
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
id = GetCurrentThreadId();
longjmp(buf, 1);
}
int main(int argc, char *argv[]) {
DWORD dwThreadIdArray = 5 ;
id = dwThreadIdArray;
if(0 == setjmp(buf))
{
printf("thread: %d sleeping\n", id);
HANDLE thread = CreateThread(NULL, 0, MyThreadFunction, NULL, 0, &dwThreadIdArray);
Sleep(1*10000);
}
else
{
printf("thread: %d\n", id);
}
return 0;
}
Redhat5.4(2.6.18-164.el5) 跑了第四个线程才挂,Centos 6.3(2.6.32-279.el6.x86_64)没挂(不过人穷该机只是单核,多核情况下不敢确认)。
但是Redhat5.4中只有一个线程一次触发肯定是没有问题的。后面发现挂掉的地方是printf, 只能说在2.6.18下printf也得加保护之类的了。
#include <stdio.h>
#include <iostream>
#include <pthread.h>
#include <setjmp.h>
using namespace std;
jmp_buf buf;
static void *doit(void *a)
{
sleep(1);
longjmp(buf, 1);
while(1)
{
sleep(300);
}
}
int main(int argc,char **argv)
{
#ifndef SETJMP_IS_THREAD_SAFE
printf("no safe\n");
#endif
if (0==setjmp(buf))
{
pthread_t id;
for (int i = 0; i < 8; i++)
{
pthread_create(&id, NULL, doit, NULL);
}
while(1)
{
sleep(30);
}
}
else
{
/==============printf("return \n");
sleep(18);
}
}