dedecms织梦内容管理系统    
首页 | java | C/C++ | PHP | 操作系统 | ajax | 脚本编程 | 安全技术 | 本站下载页 | flex | CRM | 专题 | QQ群 | 测试中心 | 会员中心 | 积分规则
  当前位置:主页>操作系统>linux>文章内容
Linux下的C编程实战之四(上)
来源:天极网软件频道 作者:宋宝华

1.Linux“线程”

  Linux内核只提供了轻量进程的支持,未实现线程模型,但Linux尽最大努力优化了进程的调度开销,这在一定程度上弥补无线程的缺陷。Linux用一个核心进程(轻量进程)对应一个线程,将线程调度等同于进程调度,交给核心完成。

  笔者曾经在《基于嵌入式操作系统VxWorks的多任务并发程序设计》(《软件报》2006年第5~12期)中详细叙述了进程和线程的区别,并曾经说明Linux是一种“多进程单线程”的操作系统。Linux本身只有进程的概念,而其所谓的“线程”本质上在内核里仍然是进程。大家知道,进程是资源分配的单位,同一进程中的多个线程共享该进程的资源(如作为共享内存的全局变量)。Linux中所谓的“线程”只是在被创建的时候“克隆”(clone)了父进程的资源,因此,clone出来的进程表现为“线程”,这一点一定要弄清楚。因此,Linux“线程”这个概念只有在打冒号的情况下才是最准确的,可惜的是几乎没有书籍留心去强调这一点。

  目前Linux中最流行的线程机制为LinuxThreads,所采用的就是线程-进程“一对一”模型,调度交给核心,而在用户级实现一个包括信号处理在内的线程管理机制。LinuxThreads由Xavier Leroy (Xavier.Leroy@inria.fr)负责开发完成,并已绑定在GLIBC中发行,它实现了一种BiCapitalized面向Linux的Posix 1003.1c “pthread”标准接口。Linuxthread可以支持Intel、Alpha、MIPS等平台上的多处理器系统。

  按照POSIX 1003.1c 标准编写的程序与Linuxthread 库相链接即可支持Linux平台上的多线程,在程序中需包含头文件pthread. h,在编译链接时使用命令:

gcc -D -REENTRANT -lpthread xxx. c

  其中-REENTRANT宏使得相关库函数(如stdio.h、errno.h中函数) 是可重入的、线程安全的(thread-safe),-lpthread则意味着链接库目录下的libpthread.a或libpthread.so文件。使用Linuxthread库需要2.0以上版本的Linux内核及相应版本的C库(libc 5.2.18、libc 5.4.12、libc 6)。

  2.“线程”控制

  线程创建

  进程被创建时,系统会为其创建一个主线程,而要在进程中创建新的线程,则可以调用pthread_create:

pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *
(start_routine)(void*), void *arg);

  start_routine为新线程的入口函数,arg为传递给start_routine的参数。

  每个线程都有自己的线程ID,以便在进程内区分。线程ID在pthread_create调用时回返给创建线程的调用者;一个线程也可以在创建后使用pthread_self()调用获取自己的线程ID:

pthread_self (void) ;

  线程退出

  线程的退出方式有三:

  (1)执行完成后隐式退出;

  (2)由线程本身显示调用pthread_exit 函数退出;

pthread_exit (void * retval) ;

  (3)被其他线程用pthread_cance函数终止:

pthread_cance (pthread_t thread) ;

  在某线程中调用此函数,可以终止由参数thread 指定的线程。

  如果一个线程要等待另一个线程的终止,可以使用pthread_join函数,该函数的作用是调用pthread_join的线程将被挂起直到线程ID为参数thread的线程终止:

pthread_join (pthread_t thread, void** threadreturn);

3.线程通信

  线程互斥

  互斥意味着“排它”,即两个线程不能同时进入被互斥保护的代码。Linux下可以通过pthread_mutex_t 定义互斥体机制完成多线程的互斥操作,该机制的作用是对某个需要互斥的部分,在进入时先得到互斥体,如果没有得到互斥体,表明互斥部分被其它线程拥有,此时欲获取互斥体的线程阻塞,直到拥有该互斥体的线程完成互斥部分的操作为止。

  下面的代码实现了对共享全局变量x 用互斥体mutex 进行保护的目的:

int x; // 进程中的全局变量
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL); //按缺省的属性初始化互斥体变量mutex
pthread_mutex_lock(&mutex); // 给互斥体变量加锁
… //对变量x 的操作
phtread_mutex_unlock(&mutex); // 给互斥体变量解除锁

  线程同步

  同步就是线程等待某个事件的发生。只有当等待的事件发生线程才继续执行,否则线程挂起并放弃处理器。当多个线程协作时,相互作用的任务必须在一定的条件下同步。

  Linux下的C语言编程有多种线程同步机制,最典型的是条件变量(condition variable)。pthread_cond_init用来创建一个条件变量,其函数原型为:

pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr);

  pthread_cond_wait和pthread_cond_timedwait用来等待条件变量被设置,值得注意的是这两个等待调用需要一个已经上锁的互斥体mutex,这是为了防止在真正进入等待状态之前别的线程有可能设置该条件变量而产生竞争。pthread_cond_wait的函数原型为:

pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);

  pthread_cond_broadcast用于设置条件变量,即使得事件发生,这样等待该事件的线程将不再阻塞:

pthread_cond_broadcast (pthread_cond_t *cond) ;

  pthread_cond_signal则用于解除某一个等待线程的阻塞状态:

pthread_cond_signal (pthread_cond_t *cond) ;

  pthread_cond_destroy 则用于释放一个条件变量的资源。

  在头文件semaphore.h 中定义的信号量则完成了互斥体和条件变量的封装,按照多线程程序设计中访问控制机制,控制对资源的同步访问,提供程序设计人员更方便的调用接口。

sem_init(sem_t *sem, int pshared, unsigned int val);

  这个函数初始化一个信号量sem 的值为val,参数pshared 是共享属性控制,表明是否在进程间共享。

sem_wait(sem_t *sem);

  调用该函数时,若sem为无状态,调用线程阻塞,等待信号量sem值增加(post )成为有信号状态;若sem为有状态,调用线程顺序执行,但信号量的值减一。

sem_post(sem_t *sem);

  调用该函数,信号量sem的值增加,可以从无信号状态变为有信号状态。


上一篇:Linux下的C编程实战之三(下)   下一篇:Linux下的C编程实战之四(下)
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论
  热点文章
·Linux常用基本命令及应用技巧
·写得蛮好的linux学习笔记
·学会在Linux下对硬盘分区
·找回Redhat的超级用户密码
·Linux下C语言编程
·GDB教程
·Cron服务配置详解
·Linux与Unix二大操作系统编程的
·Linux 2.6 内核的嵌入式系统应用
·Linux和Windows系统调用的比较
·vim命令(一)
·vim 命令(二)
  相关文章
·Linux下的C编程实战之三(下)
·Linux下的C编程实战之四(下)
·Linux下的C编程实战之三(上)
·Linux下的C编程实战之文件系统编
·Linux下的C编程实战之开发平台搭
·资深Linux程序员的开发经验谈(下
·资深Linux程序员的开发经验谈(上
·黑客高级技巧 Linux后门技术及实
·黑客高级技巧 Linux后门技术及实
·Linux系统下C语言编程工具详细介
·Linux系统下C语言编程工具详细介
·Linux系统下的C语言开发都需要学
  相关信息
copy right @ 百家拳软件项目研究室 2007 辽ICP备07011763