现在的位置: 首页 > 综合 > 正文

linux程序设计笔记12:POSIX线程

2013年02月15日 ⁄ 综合 ⁄ 共 2107字 ⁄ 字号 评论关闭

由于fork的代价太高,我们可以使用线程来使多件事情以一种非常紧密的方式同时发送。

线程:进程中多个执行路线。 是一个进程内部的一个控制序列。

1. 当进程中创建一个线程时,新的执行线程将拥有自己的栈,但与它的创建者共享全局变量、文件描述符、信号处理函数和当前目录状态。

2.为了使用线程编程:我们要包含宏_REENTRANT,他包含在pthread.h头文件中,并且编译程序时需要我们用选项-lpthread来连接线程库 。

3.可重入:可重入代码别多次调用后而仍然正常工作

4.编写多线程程序时,我们通过定义宏:_REENTRANT来告诉编译器我们需要可重入功能,这个宏的定义必须位于所有#include 语句之前。

5.创建新线程:pthread_create() ..

 #include <pthread.h>  int pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void*),void *arg);

参数1:一个表示新线程的标识符:类型pthread_t  

参数2:属性(一般设为NULL即可) 

参数3:要启动的函数;  这是一个返回void*  ,参数为void*的函数。 因为是void*,那么表示:我们可以传递任意类型,和返回任意类型了。哈哈。牛逼!

参数4:该函数的参数。

6. 线程终止:pthread_exit()   进程终止:exit()

  pthread_join () 函数在线程中的作用,等价于进程中用来收集进程信息的wait()函数。参数1:线程标识符  参数2:该线程的返回值指针的指针。

 

线程程序的测试与练习,我们经常使用sleep()来达到查看程序运行效果。

 

线程同步:

1.信号量:一段代码的看门人。适用于控制一组对象的访问,比如5根电话线中分配1条给某个线程。。。

2.互斥量:一段代码的互斥设备。适用于任意时刻只允许一个线程可以访问了共享内存。

一个程序中的多个线程试图改变一个信号量的值,系统将保证所有的操作都将依次进行。但如果是普通变量,就无法保证该变量的确定性。

 

3.信号量分有:1. 二进制信号量 0 1   2. 计数信号量

  二进制信号量:常用来保护一段代码,使其每次只能被一个执行线程运行。我们可以使用二进制信号量。

  计数信号量: 可以允许有限数目的线程执行一段指定的代码,我们可以使用计数信号量。

(计数信号量仅仅值二进制信号量的一种拓展,并不常用,他们实际调用的函数都是一样的。)

4.信号量的函数以:sem_开头。线程中使用的信号量函数有4个。 #include <semaphore.h>

  1. 创建信号量函数:  sem_init() ;

  2. sem_wait(); 安全的使信号量减1,以原子操作的方式,不会引起冲突。该函数会在当信号量为0时,等待另一个线程+1之后,才去减一。不会减成-1.sem_trywait()非阻塞版

  3. sem_post();  安全的使信号量加1,以原子操作的方式,不会引起冲突。(信号量在这种“单个函数中能原子化地进行测试和设置”的能力使其变得非常有价值的。)

  4.sem_destroy();对它的资源进行清理。(如果该信号量正别一些线程等待,那么清理会失败。 成功返回0.)

所得:线程是同步的,就在这同步的其中,为了控制先后次序,我们使用:信号量。来导致某一个线程等待,某一个线程执行着。wait() post()的使用便是在其中的先后控制。

二。线程同步的另一种方法:互斥量。pthread_mutex_t 类型。

互斥量:他允许锁住某个对象,使得每次只能有一个线程访问它。为了控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后解锁他。

(用于互斥量的函数和信号量的函数非常相似) pthread_mutex_init () pthread_mutex_lock()  pthread_mutex_unlock() pthread_mutex_destroy()

所得:互斥量利用的也是他的阻塞罗!! 再试图加上没有释放的锁,会导致阻塞,编程即利用了这个特性。来相互判断,相互协调同步的。相互等待呗。二进制信号量也是一样。

三。线程属性:

我们可以设置线程属性来达到更高级的线程那个。。。。

1.  pthread_attr_init () 该函数初始化一个线程属性对象。

 2. pthread_attr_destroy() 该函数是对属性对象进行清理和回收工作。

四。取消一个线程。

 pthread_cancel() ; #include <pthread.h> int pthread_cancel(pthread_t thread);

 线程可以发送取消请求给另一个线程,但是另一个线程是否取消,要看他如何处理这个取消请求。

 pthread_setcancelstate(int state,int *oldstate); 这个函数可以设置:接受取消请求,也可以忽略取消请求。

pthread_setcanceltype(int type,int *oldtype); 这个可以设置取消类型:是立即呢,还是等函数都运行完了呢?

 

抱歉!评论已关闭.