对于C,哪些绿色线程库可以与Haskell';的性能和易用性相匹配;什么是绿色线?

对于C,哪些绿色线程库可以与Haskell';的性能和易用性相匹配;什么是绿色线?,c,networking,haskell,concurrency,green-threads,C,Networking,Haskell,Concurrency,Green Threads,在Haskell中编程时,我非常习惯于依赖GHC的轻便线程 什么样的C等价库可以提供相同的可伸缩性和易用性 具体来说,我需要至少以下两个函数的C等价物 forkIO :: IO () -> IO ThreadId killThread :: ThreadId -> IO () 我假设对于我的应用程序,如果线程只打开阻塞操作而不是强制挂起就足够了,因为所有线程都会频繁地为网络IO阻塞,我只使用splice系统调用来请求Linux内核在套接字之间推送数据

在Haskell中编程时,我非常习惯于依赖GHC的轻便线程

什么样的C等价库可以提供相同的可伸缩性和易用性

具体来说,我需要至少以下两个函数的C等价物

forkIO     :: IO () -> IO ThreadId
killThread ::             ThreadId -> IO ()
我假设对于我的应用程序,如果线程只打开阻塞操作而不是强制挂起就足够了,因为所有线程都会频繁地为网络IO阻塞,我只使用
splice
系统调用来请求Linux内核在套接字之间推送数据


更新

有数字和表格比较


结果有利于原型线程。由于我没有使用过任何库,而且可能还有其他库,所以我很想听听使用/开发过此类库的任何人的意见。

使用POSIX线程。它们在任何现代实现上都是“绿色”的,不是“绿色线程”的意义,而是轻量级和高效的意义。没有可移植的方法可以在普通C或POSIX减去线程的基础上滚动自己的线程。正如OP所提到的,有些库以不可移植的方式实现绿色线程/协同例程(通常尽管声称可移植)

最接近可移植的方法是使用
makecontext
/
swapcontext
,不幸的是,这不能很好地执行,因为它必须进行系统调用来保存/恢复“线程”之间每个开关上的信号掩码。这使得在“绿色”线程之间的切换比在“真正的”POSIX线程实现上的内核级线程之间的上下文切换更昂贵,并且基本上否定了“绿色线程”所声称的任何好处

不关心信号掩码的不可移植方法可以使用特定于机器的asm完全在用户空间中进行上下文切换,理论上性能优于内核级线程,但一旦引入IO,性能将再次失控,因为即将执行IO的线程必须首先进行昂贵的测试,以检查操作是否会阻塞,如果是,则将控制权移交给另一个线程


我坚持我的立场,“绿色线程”是一个时代早已过去的想法。这似乎也是奥斯汀集团(负责POSIX)的立场,他们删除了POSIX 2008中的
ucontext
函数,并建议用POSIX线程替换(现在是一项强制性功能)。

我不再对以下代码有评论,也没有任何示例- 这是一个作为预处理器宏实现的可移植(伪)线程库

     typedef struct
     {
     unsigned int magic;
     unsigned short ctx;
     unsigned char is_destroyed;
     }
     _run;

     typedef struct
     {
     unsigned int magic;
     unsigned int cnt;
     }
     _sem;


     #define aa_RUNNER_WAITING             0
     #define aa_RUNNER_YIELDED             1
     #define aa_RUNNER_EXITED              2
     #define aa_RUNNER_ENDED               3

     #define aaRunnerCreate(rp)            (rp)->magic='runr'; (rp)->ctx=0; (rp)->is_destroyed=NO
     #define aaRunnerDestroy(rp)           (rp)->is_destroyed=YES

     #define aaRunnerThread(args)          C args
     #define aaRunnerBegin(rp)             { C yflag=YES; if(yflag) {}  switch((rp)->ctx) { case 0:
     #define aaRunnerEnd(rp)               } yflag=NO; if(yflag) {}  aaRunnerCreate(rp); return aa_RUNNER_ENDED; }

     #define aaRunnerWaitUntil(rp,condx)   do  { (rp)->ctx=__LINE__; case __LINE__: if(!(condx))  { return aa_RUNNER_WAITING;  }  } while(0)
     #define aaRunnerWaitWhile(rp,condi)   aaRunnerWaitUntil((rp),!(condi))
     #define aaRunnerWaitThread(rp,thr)    aaRunnerWaitWhile((rp),aaRunnerSchedule(thr))
     #define aaRunnerWaitSpawn(rp,chl,thr) do { aaRunnerCreate((chl));  aaRunnerWaitThread((rp),(thr)); } while(0)

     #define aaRunnerRestart(rp)           do { aaRunnerCreate(rp); return aa_RUNNER_WAITING; } while(0)
     #define aaRunnerExit(rp)              do { aaRunnerCreate(rp); (rp)->magic=0; return aa_RUNNER_EXITED;  } while(0)

     #define aaRunnerSchedule(f)           ((f)<aa_RUNNER_EXITED)
     #define aaRunnerYield(rp)             do { yflag=NO; (rp)->ctx=__LINE__; case __LINE__: if(!yflag||!((rp)->is_destroyed))  { return aa_RUNNER_YIELDED;  }  } while(0)
     #define aaRunnerYieldUntil(rp,condi)  do { yflag=NO; (rp)->ctx=__LINE__; case __LINE__: if(!yflag||!(condi)) { return aa_RUNNER_YIELDED;   }   } while(0)

     #define aaRunnerSemInit(sp,c)         (sp)->magic='runs'; (sp)->cnt=c
     #define aaRunnerSemWait(rp,sp)        do { aaRunnerWaitUntil(rp,(sp)->cnt>0); --(sp)->cnt;  } while(0)
     #define aaRunnerSemSignal(rp,sp)      ++(sp)->cnt
typedef结构
{
无符号整数魔术;
无符号短ctx;
未签名字符被销毁;
}
_运行;
类型定义结构
{
无符号整数魔术;
无符号int-cnt;
}
_扫描电镜;
#定义aa_RUNNER_WAITING 0
#定义aa_RUNNER_1
#定义aa_RUNNER_退出2
#定义aa_RUNNER_结束3
#定义aaRunnerCreate(rp)(rp)->magic='runr';(rp)->ctx=0;(rp)->是否已销毁=否
#定义Arunnerdestroy(rp)(rp)->是否已销毁=是
#定义aaRunnerThread(args)C args
#定义aaRunnerBegin(rp){cyflag=YES;如果(yflag){}开关((rp)->ctx){情况0:
#定义aarunnered(rp)}yflag=NO;如果(yflag){}aaRunnerCreate(rp);返回aa_RUNNER_end;}
#定义aaRunnerWaitUntil(rp,condx)do{(rp)->ctx=\uuuuuuuu-LINE\uuuuuu;case\uuuuuu-LINE\uuuuuuuuuu:if(!(condx)){return aa\u-RUNNER\u-WAITING;}while(0)
#定义aaRunnerWaitWhile(rp,condi)aaRunnerWaitUntil((rp),!(condi))
#定义aaRunnerWaitThread(rp,thr)aaRunnerWaitWhile((rp),aaRunnerSchedule(thr))
#定义aaRunnerWaitSpawn(rp,chl,thr)do{aaRunnerCreate((chl));aaRunnerWaitThread((rp),(thr));}while(0)
#定义aaRunnerRestart(rp)do{aarunnerrate(rp);在(0)时返回aa_RUNNER_WAITING;}
#定义aaRunnerExit(rp)do{aarunnerecreate(rp);(rp)->magic=0;返回aa_RUNNER_EXITED;}while(0)
#定义aaRunnerSchedule(f)((f)ctx=uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu线:如果(!yflag | |!((rp)->被销毁)){return aa_uuuu
#定义aaRunnerYieldUntil(rp,condi)do{yflag=NO;(rp)->ctx=uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#定义aaRunnerSemInit(sp,c)(sp)->magic='runs';(sp)->cnt=c
#定义aaRunnerSemWait(rp,sp)do{aaRunnerWaitUntil(rp,(sp)->cnt>0);-(sp)->cnt;}while(0)
#定义运行信号(rp,sp)+(sp)->cnt

libMill可能就是您要搜索的内容:

它以Go-Lang通道样式实现用户级线程


它是由超级聪明的Martin sústrik开发的,他是ZeroMQ的创建者。所以它一定很好☺

我敢说libHSrts.a的
foreign export
?(也就是说,只需使用GHC运行时,毕竟它是一个C库)也就是说,GHC运行时是5万行C,并且。您需要一个epoll包装器。至于最后一个问题:编写正确的函数原型并链接到
-lHSrts
@KenWhite公平地说,OP确实指出了标准,或者至少是一个入口阈值:Haskell绿色线程的性能和易用性。他继续提供对特定Haskell函数的引用,这些函数需要C等价物。措辞可能不太理想,但总体而言,问题显然在“我应该在下一个web项目中使用Python还是Ruby?”键入不需要的推测。@user4815162342:我理解,因此没有投票结束问题;但是,问题的主题(标题)问“什么是最好的”,这违反了指导原则,