linux程序设计复习总结(九)POSIX线程

1.线程是一个进程内部的一个控制序列。

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

2.优点:一个程序同时做两件以上事很有必要。混杂着输入输出计算的程序,将不同部分分为不同的线程执行可以改善程序性能。多线程对资源的需求比多进程小。

缺点:容易出错难调试,多线程不一定适合所有程序。

3.多线程程序,必须定义宏_REENTRANT(定义必须位于#include语句之前),在程序中包含头文件pthread.h,并且在编译程序时需要用选项-1pthread来链接线程库。

#include <pthread.h>

创建线程:
thread:新线程的线程标识符的存放位置
attr:设置线程属性,不需要特殊属性的话一般为NULL
start_routine:线程函数地址,返回值void *,参数void *
arg:函数参数
成功返回0
int pthread_create(pthread_t *thread, pthread_attr_t *attr, (void *)(*start_routine)(void *),void *arg);
等待线程结束:
th:线程号
thread_return:线程的返回值的地址
int pthread_join(pthread_t th,void **thread_return);
结束线程:
retval:返回值,随便啥,只要不是局部变量的指针
int pthread_exit(void *retval);

4.信号量和互斥量提供了控制线程执行和访问代码临界区域的方法。

信号量是一个特殊类型的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作,即使在一个多线程程序中也是如此。如果一个程序中有两个(或更多)的线程试图改变一个信号量的值,系统将保证所有的操作都将依次进行。

信号量一般常用来保护一段代码,使其每次只能被一个执行线程运行,要完成这个工作,就要使用二进制信号量。有时,我们希望可以允许有限数目的线程执行一段指定的代码,这就需要用到计数信号量。

#include <semaphore.h>

初始化sem指向的信号量对象,psharedpshared参数控制信号量的类型,如果其值为0,就表示这个信号量是当前进程的局部信号量,value是给信号量一个初值。
int sem_init(sem_t *sem, int pshared, unsigned int value);
post信号量+1
int sem_post(sem_t *sem);
wait信号量-1
int sem_wait(sem_t *sem);
清理用完的信号量
int sem_destroy(sem_t *sem);

在多线程程序中,需要对时序考虑得非常仔细。

另一种用在多线程程序中的同步访问方法是使用互斥量。它允许程序员锁住某个对象,使得每次只能有一个线程访问它。为了控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后解锁它。

#include <pthread.h>

mutexattr设置互斥量的属性,属性控制互斥量的行为,默认为NULL
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
上锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
销毁
int pthread_mutex_destroy(pthread_mutex_t *mutex);

5.脱离线程:不需要第二个线程向主线程返回信息,也不想让主线程等待它的结束。我们可以创建这一类型的线程,它们被称为脱离线程(detached thread)。可以通过修改线程属性或调用pthread_ detach的方法来创建它们。

#include <pthread.h>

初始化一个线程属性对象
int pthread_attr_init(pthread_attr_t *thread_attr);
pthread_attr_setdetachstate的线程属性选项可选PTHREAD_CREATE_JOINABLE和PTHREAD_CREATE_DETACHED,选择后者即设置为脱离线程属性
int pthread_attr_setdetachstate(pthread_attr_t *thread_attr, int detachstate);
传入设置好的线程属性对象来创建新线程,则创建出一个脱离线程
int pthread_create(pthread_t *thread, pthread_attr_t *attr, (void *)(*start_routine)(void *),void *arg);
销毁线程属性对象
void pthread_attr_destroy(pthread_attr_t *thread_attr);

6.有时,想让一个线程可以要求另一个线程终止,就像给它发送一个信号一样。线程有方法可以做到这一点,与信号处理一样,线程可以在被要求终止时改变其行为。

发出取消请求的一端,只需要提供线程号,调用pthread_cancel。
接收取消信号的一端,要调用pthread_setcancelstate来确定是否接受取消请求.state为PTHREAD_CANCEL_ENABLE则接收,为PTHREAD_CANCEL_DISABLE,则忽略取消请求。
oldstate获取先前的消息状态,可为NULL。
还要调用pthread_setcanceltype来设置退出方式,
type为PTHREAD_CANCEL_ASYNCHRONOUS,接收到取消请求后立即采取行动,为PTHREAD_CANCEL_DEFERRED则等待直到线程执行了下述函数之一后才采取行动:pthread_join、pthread_cond_wait、pthread_cond_timedwait、pthread_testcancel、sem_wait或sigwait.

#include <pthread.h>

int pthread_cancel(pthread_t a_thread);
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值