其中绿色线程库可用于C,可以匹配使用Haskell的绿色线程的性能和易用性? [关闭](Whic

2019-08-07 02:53发布

我非常习惯于依靠GHC的forkIO在Haskell编程时便携式轻量级线程。

什么是对C,可以提供相同的scalibility和易用性的等价库?

具体来说,我需要至少以下两种功能C-当量。

forkIO     :: IO () -> IO ThreadId
killThread ::             ThreadId -> IO ()

我想我的应用程序,这将是不够的,如果线程只在阻塞操作,而不是被强制暂停,因为所有的线程块高度频繁的网络IO和我只用交换splice系统调用来要求Linux内核插座之间的推搡数据。


更新

本文有数字和表格比较

  • GNU第P
  • Protothreads
  • PM2包裹

有利于结果Protothreads。 由于我没有使用任何有也可能是其他图书馆,我很想从人谁使用了/开发了这样的库听到。

Answer 1:

libMill可能是你要搜索的内容: http://libmill.org/

它实现了在围棋郎通道风格的用户级线程。

而且它由超级智能马丁Sústrik,ZeroMQ的创造者开发http://250bpm.com/ 。 所以它一定是好的☺



Answer 2:

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

     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


Answer 3:

使用POSIX线程。 他们在任何现代实现“绿色”,而不是“绿色线程”的感觉,但在轻量和高效率的意识。 有上滚来滚纯C或POSIX线程减去顶你自己的线程没有可移植的方法。 作为OP提到的,有一些库实现在非便携的方式绿色线程/协同例程(通常尽管声称的可移植性)。

最近到便携的方法是使用makecontext / swapcontext ,可惜这不能表现良好,因为它使系统调用保存/恢复“线程”之间的每个开关上的信号屏蔽。 这使得“绿色”主题不是“真正的” POSIX线程执行内核级线程之间的上下文切换更加昂贵之间的切换,基本否定了“绿色线程”的任何声称好处。

不关心的信号掩码可以使用特定的机器ASM做上下文在用户空间完全切换,理论上性能比内核级线程更好,但性能再次将尽快飞出窗外不可移植的方法你介绍IO,因为一个线程,是关于执行IO就必须首先做昂贵的测试,以检查是否操作将阻塞,如果是这样,翻身控制不同的线程。

我坚持我的立场,即“绿色线程”是一个理念的时代早已过去。 这也似乎是奥斯汀组(负责POSIX),谁移走的位置ucontext 2008年POSIX功能,并建议更换与POSIX线程(这是现在强制性的特征)。



文章来源: Which green threads libraries are available for C that can match the performance and ease of use of Haskell's green threads? [closed]