piggy
驱动牛犊
驱动牛犊
  • 注册日期2001-08-24
  • 最后登录2012-01-14
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望27点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
阅读:3005回复:10

Linux下的进程和线程

楼主#
更多 发布于:2002-01-12 23:55
在Linux下有没有线程的概念,是不是在Linux下运行的都是进程。也就是说一个进程只能去创建它的子进程(利用fork),而不能去创建属于它的一个线程。如果能够创建线程的话,如何创建?

我想写一个server端的程序,它要响应不同的client端的请求。如果对每一个请求都创建一个进程的话,是不是很占用系统资源?如果有很多个请求,server就会运行得很慢? 请各位指教。



znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
沙发#
发布于:2002-01-13 12:19
unix下的fork创建的是轻量级进程,也就是介于线程和进程之间...
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
alibaba
驱动牛犊
驱动牛犊
  • 注册日期2002-01-17
  • 最后登录2002-01-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-01-17 13:05
pthread线程库
sunsetyang
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2007-03-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-01-28 23:41
    用fork和pthread的资源占用方面是差不多的。反正在单cpu的环境下使用pthread并不会带来任何效率上的提高。很有可能还会因为用进程模拟线程的时候引入其他的开销。
    建议使用fork.在其它的有thread支持的系统上应该优先考虑线程,毕竟进程切换的开销还是比较大的。
    
[color=red]Optimization[/color] In Progress . . . Welcome to http://mail.ustc.edu.cn/~chyang/
ramble
驱动牛犊
驱动牛犊
  • 注册日期2001-09-30
  • 最后登录2002-04-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-02-04 13:51
严格的说,Linux中只有进程和轻量级进程,轻量级进程有
单独的task_struct,但是可以和其他进程共享虚存,信号
处理,文件系统,以及文件管理等资源中的任意一种或者
几种。Linux的pthread最后还是用的clone来实现的线程,
clone在内核中同样是使用的do_fork()。
顺便说一句,在用户态不难实现完全用户级的线程。不过
对于你的程序不会有帮助。
Ramble over the world
cmdcmd
驱动牛犊
驱动牛犊
  • 注册日期2002-02-08
  • 最后登录2005-02-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-02-09 04:36
Pthread(POSIX thread线程库)

线程库pthread.h(线程库)
编译命令是cc -mt [选项] 源文件 -lpthread ptherad.h

使用线程的步骤:
(1)引用库:
#include <pthread.h>
(2)定义两个描述变量
pthread_t tid; /*线程描述变量*/
pthread_attr_t tattr; /*线程属性描述变量*/
(3)初始化变量
pthread_attr_init(&tattr);
初始化线程属性描述变量
pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
设置线程的视野为“系统”
(4)创建线程
pthread_create(&tid, &tattr, start_function, argument);
其中tid和tattr是两个定义过的线程描述变量和线程属性描述变量,start_function是线程所执行的函数,argument是传递给函数的变量。
pthread_exit(value);
可以用来结束一个线程,value是返回值(可以为NULL)。如果线程所调用的函数执行完毕,线程也会自动调用pthread_exit()来结束线程。
如果需要父线程等待子线程,可以使用
pthread_join(tid, value_ptr);
其中tid是子线程的线程描述变量,value_ptr是存储子线程返回值的地址。

线程控制可以使用mutex,要现声明一个mutex描述变量和一个mutex属性描述变量:
pthread_mutex_t mt;
pthread_mutexattr_t mta;
然后进行初始化:
pthread_mutexattr_init(&mta)
pthread_mutex_init(&mt, &mta)

也可以直接调用系统提供的常数:
pthread_mutex_t mt= PTHREAD_MUTEX_INITIALIZER;
这两种方法是等同的。
销毁一个mutex可以使用
pthread_mutex_destroy(&mt);

关于进程控制,有
pthread_mutex_lock(&mt)来锁住一个线程
pthread_mutex_trylock(&mt)来试图锁住一个线程
pthread_mutex_unlock(&mt)来为一个线程开锁

还可以使用conditional variable
类似mutex的有:
pthread_cond_t cv;
pthread_condattr_t cva;
然后进行初始化:
pthread_condattr_init(&cva)
pthread_cond_init(&cv, &cva)

也可以直接调用系统提供的常数:
pthread_cond_t cv= PTHREAD_COND_INITIALIZER;
销毁一个conditional variable使用
pthread_cond_destroy(&cv);

初始化之后可以有(注意,一定要和mutex一起使用)
使用
pthread_cond_wait(&cv, &mt);
来迫使线程等待一个conditional variable
使用
pthread_cond_signal(&cv);
来唤醒conditional variable队列中的第一个等待的线程
pthread_cond_broadcast(&cv);
来唤醒conditional variable队列中所有等待的线程

此外,还可以使用semaphore,但是要调用其它的库(semaphore.h或者synch.h)
基本的POSIX线程就这么多了,不清楚的可以去差manual
man pthread_create
等等会给出每个函数的详细用法。

如果需要范例程序,我可以给你几个简单的程序。 :P
[size=6][color=red]I Love You All.[/color][/size]
piggy
驱动牛犊
驱动牛犊
  • 注册日期2001-08-24
  • 最后登录2012-01-14
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望27点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-02-09 05:49
在Advanced Linux Programming那本书里有很详细的介绍,本站就有下载。
luocs
驱动牛犊
驱动牛犊
  • 注册日期2002-03-09
  • 最后登录2002-03-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-03-09 08:58
LINUX下是有创建线程的函数,直接调用就行了,不过要考虑用线程的时候,有些纯c函数是不安全的如strtok等,client请求server时linux有最大进程数限制,但我感觉瓶井应在通讯而不在server的能力。(一般应用的话)
luocs
eastman
驱动小牛
驱动小牛
  • 注册日期2001-12-02
  • 最后登录2004-02-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-03-27 20:30
用户模式和内核模式都可实现线程,但两者具有不同的优缺点,比如说用户模式下的多线程在有阻塞的地方就用的不好,因为同一进程中
的所有线程将都被阻塞,因为内核将他门当作一个运行对象。而内核模式下,会使得对线程的同步以及文件共享等带来复杂性。
李问
sc_yang
驱动牛犊
驱动牛犊
  • 注册日期2002-04-11
  • 最后登录2008-10-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-04-11 17:57
其是在现在的应用环境下,server端利用fork()为多个客户端服务的效率还是很高的。我建议就采用fork(),既简单又熟悉。
我驱,我驱,我驱驱驱
zhengq
驱动牛犊
驱动牛犊
  • 注册日期2002-03-05
  • 最后登录2003-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-04-19 22:48
Linux的并发机制建立在进程之上,内核使用的是sys_fork来创建进程。进程创建时要将父进程的进程控制块(内核中为task结构)全部复制。在Linux中线程的实现分核心线程和用户线程,用户线程由线程库实现,无法参与全局调度,而核心线程由内核实现,可参与全局调度,实际是sys_clone系统调用来实现的。sys_clone和sys_fork的不同之处在于sys_clone可有选择性的复制,即可实现轻量级进程,所以核心线程即轻量级进程,而不是象Windows NT/2000/XP、Solaris等系统中实现的内核态线程,因为Linux在内核态是不并发执行的,系统调度是主动调用的。可以在Java的Thread执行时看到Java虚拟机执行的线程有不同的进程ID(使用ps)。
游客

返回顶部