1 Star 2 Fork 0

interesting-goods/libtask

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT
(Fork addendum: This is a fork of libtask that adds support for epoll()
and other thing helpful for writing high-performance network servers
using libtask on Linux.

Now back to your regularly scheduled README.  -jamwt)

--------------------------------------------------------------------------------

Libtask is a simple coroutine library.  It runs on Linux (ARM, MIPS, and x86),
FreeBSD (x86), OS X (PowerPC x86, and x86-64), and SunOS Solaris (Sparc),
and is easy to port to other systems.

Libtask gives the programmer the illusion of threads, but
the operating system sees only a single kernel thread.
For clarity, we refer to the coroutines as "tasks," not threads.

Scheduling is cooperative.  Only one task runs at a time,
and it cannot be rescheduled without explicitly giving up
the CPU.  Most of the functions provided in task.h do have
the possibility of going to sleep.  Programs using the task
functions should #include <task.h>.

--- Basic task manipulation

int taskcreate(void (*f)(void *arg), void *arg, unsigned int stacksize);

	Create a new task running f(arg) on a stack of size stacksize.

void tasksystem(void);

	Mark the current task as a "system" task.  These are ignored
	for the purposes of deciding the program is done running
	(see taskexit next).
	
void taskexit(int status);

	Exit the current task.  If this is the last non-system task,
	exit the entire program using the given exit status.

void taskexitall(int status);

	Exit the entire program, using the given exit status.

void taskmain(int argc, char *argv[]);

	Write this function instead of main.  Libtask provides its own main.

int taskyield(void);
	
	Explicitly give up the CPU.  The current task will be scheduled
	again once all the other currently-ready tasks have a chance
	to run.  Returns the number of other tasks that ran while the
	current task was waiting.  (Zero means there are no other tasks
	trying to run.)

int taskdelay(unsigned int ms)

	Explicitly give up the CPU for at least ms milliseconds.
	Other tasks continue to run during this time.

void** taskdata(void);

	Return a pointer to a single per-task void* pointer.
	You can use this as a per-task storage place.

void needstack(int n);

	Tell the task library that you need at least n bytes left
	on the stack.  If you don't have it, the task library will call abort.
	(It's hard to figure out how big stacks should be.  I usually make
	them really big (say 32768) and then don't worry about it.)

void taskname(char*, ...);

	Takes an argument list like printf.  Sets the current task's name.
	
char* taskgetname(void);

	Returns the current task's name.  Is the actual buffer; do not free.
	
void taskstate(char*, ...);
char* taskgetstate(void);

	Like taskname and taskgetname but for the task state.
	
	When you send a tasked program a SIGQUIT (or SIGINFO, on BSD)
	it will print a list of all its tasks and their names and states.
	This is useful for debugging why your program isn't doing anything!

unsigned int taskid(void);

	Return the unique task id for the current task.

--- Non-blocking I/O

There is a small amount of runtime support for non-blocking I/O
on file descriptors.  

int fdnoblock(int fd);

	Sets I/O on the given fd to be non-blocking.  Should be
	called before any of the other fd routines.

int fdread(int, void*, int);

	Like regular read(), but puts task to sleep while waiting for
	data instead of blocking the whole program.

int fdwrite(int, void*, int);

	Like regular write(), but puts task to sleep while waiting to
	write data instead of blocking the whole program.

void fdwait(int fd, int rw);

	Low-level call sitting underneath fdread and fdwrite.
	Puts task to sleep while waiting for I/O to be possible on fd.
	Rw specifies type of I/O: 'r' means read, 'w' means write,
	anything else means just exceptional conditions (hang up, etc.)
	The 'r' and 'w' also wake up for exceptional conditions.

--- Network I/O

These are convenient packaging of the ugly Unix socket routines.
They can all put the current task to sleep during the call.  

int netannounce(int proto, char *address, int port)

	Start a network listener running on address and port of protocol.
	Proto is either TCP or UDP.  Port is a port number.  Address is a
	string version of a host name or IP address.  If address is null,
	then announce binds to the given port on all available interfaces.
	Returns a fd to use with netaccept.
	Examples: netannounce(TCP, "localhost", 80) or 
		netannounce(TCP, "127.0.0.1", 80) or netannounce(TCP, 0, 80).

int netaccept(int fd, char *server, int *port)

	Get the next connection that comes in to the listener fd.
	Returns a fd to use to talk to the guy who just connected.
	If server is not null, it must point at a buffer of at least
	16 bytes that is filled in with the remote IP address.
	If port is not null, it is filled in with the report port.
	Example:
		char server[16];
		int port;
		
		if(netaccept(fd, server, &port) >= 0)
			printf("connect from %s:%d", server, port);

int netdial(int proto, char *name, int port)

	Create a new (outgoing) connection to a particular host.
	Name can be an ip address or a domain name.  If it's a domain name,
	the entire program will block while the name is resolved
	(the DNS library does not provide a nice non-blocking interface).
	Example: netdial(TCP, "www.google.com", 80)
		or netdial(TCP, "18.26.4.9", 80)

--- Time

unsigned int taskdelay(unsigned int ms)

	Put the current task to sleep for approximately ms milliseconds.
	Return the actual amount of time slept, in milliseconds.

--- Example programs

In this directory, tcpproxy.c is a simple TCP proxy that illustrates
most of the above.  You can run

	tcpproxy 1234 www.google.com 80

and then you should be able to visit http://localhost:1234/ and see Google.

Other examples are:
	primes.c - simple prime sieve
	httpload.c - simple HTTP load generator
	testdelay.c - test taskdelay()

--- Building

To build, run make.  You can run make install to copy task.h and
libtask.a to the appropriate places in /usr/local.  Then you
should be able to just link with -ltask in your programs
that use it.  

On SunOS Solaris machines, run makesun instead of just make.

--- Contact Info

Please email me with questions or problems.

Russ Cox
rsc@swtch.com


--- Stuff you probably won't use at first ---
--- but might want to know about eventually ---

void tasksleep(Rendez*);
int taskwakeup(Rendez*);
int taskwakeupall(Rendez*);

	A Rendez is a condition variable. You can declare a new one by
	just allocating memory for it (or putting it in another structure)
	and then zeroing the memory.  Tasksleep(r) 'sleeps on r', giving
	up the CPU.  Multiple tasks can sleep on a single Rendez.
	When another task comes along and calls taskwakeup(r), 
	the first task sleeping on r (if any) will be woken up.
	Taskwakeupall(r) wakes up all the tasks sleeping on r.
	They both return the actual number of tasks awakened.



void qlock(QLock*);
int canqlock(QLock*);
void qunlock(QLock*);

	You probably won't need locks because of the cooperative 
	scheduling, but if you do, here are some.  You can make a new
	QLock by just declaring it and zeroing the memory.
	Calling qlock will give up the CPU if the lock is held by someone else.
	Calling qunlock will not give up the CPU.
	Calling canqlock tries to lock the lock, but will not give up the CPU.
	It returns 1 if the lock was acquired, 0 if it cannot be at this time.

void rlock(RWLock*);
int canrlock(RWLock*);
void runlock(RWLock*);

void wlock(RWLock*);
int canwlock(RWLock*);
void wunlock(RWLock*);

	RWLocks are reader-writer locks.  Any number of readers
	can lock them at once, but only one writer at a time.
	If a writer is holding it, there can't be any readers.
	

Channel *chancreate(int, int);
etc.

	Channels are buffered communication pipes you can
	use to send messages between tasks.  Some people like
	doing most of the inter-task communication using channels.
	
	For details on channels see the description of channels in
	http://swtch.com/usr/local/plan9/man/man3/thread.html and
	http://swtch.com/~rsc/thread/
	and also the example program primes.c, which implements
	a concurrent prime sieve.
This software was developed as part of a project at MIT. Copyright (c) 2005-2007 Russ Cox, Massachusetts Institute of Technology Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. === Contains parts of an earlier library that has: /* * The authors of this software are Rob Pike, Sape Mullender, and Russ Cox * Copyright (c) 2003 by Lucent Technologies. * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */

简介

c语言协程库 展开 收起
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/interesting-goods/libtask.git
git@gitee.com:interesting-goods/libtask.git
interesting-goods
libtask
libtask
master

搜索帮助