linux线程详解

linux线程在服务器开发和嵌入式开发特别重要因为线程的恰当开启会让程序整体达到一个流水线效果
1.线程创建
pthread_create(线程id,线程属性);
pthreat_t pthread_id;

线程属性

typedef struct __pthread_attr_s
{
int __detachstate; 设置可取消属性

int __schedpolicy;    调度策略

struct __sched_param __schedparam;

int __inheritsched;

int __scope;

size_t __guardsize;
int __stackaddr_set;

void *__stackaddr;
size_t __stacksize;表示堆栈的大小。

}pthread_attr_t;
线程id 好理解 直接创建一个id 然后通过pthread_create 自动会创建好一个id 那么线程属性是什么 在核心数目多的时候 我们可以通过指定pthread_attr_t 的属性 int __schedpolicy; 让我们的线程各自绑定一个核心 因为cpu在执行一个线程的时候 当另一个线程切换到同一个cpu的时候 之前的线程会被保存当前的状态到tss段 然后另一个线程进入cpu执行 而且上一个线程的内部变量都会被下一个线程替换 那么如果线程大量的时候这种反复的调用 会降低效率 那么我们通过每个线程绑定一个核心 就会让效率大大提升 实现并行
pthread_t pthread_self(void);

__detachstate
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);

struct __pthread_attr_s attr;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthrea_create(tid,&attr,func,argv);

PTHREAD_CREATE_DETACHED—>不能被等待
PTHREAD_CREATE_JOINABLE—>

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);

线程退出与等待

void pthread_exit(void *retval);

  • 自行调用pthread_exit
  • 其他线程调用 pthread_cancel
  • 线程执行结束
  • 创建线程的进程退出
  • 其中一个线程执行了exec类函数,因为会替换当前进程所有的地址空间
    子线程退出仅释放自己私有空间,私有栈空间

int pthread_join(pthread_t thread, void **retval);

void pthread_cleanup_push(void (*routine)(void *), void *arg);
void pthread_cleanup_pop(int execute);
解决线程终止或者异常终止时,释放资源的问题

线程取消

线程能否被取消要看两点:

  • 线程是否具有可取消属性—默认可以被取消

  • 线程如果设置为到可取消点才能被取消时,线程不会被立刻取消

    int pthread_cancel(pthread_t thread);

线程的取消状态属性
int pthread_setcancelstate(int state, int *oldstate);
可取消 不可取消
PTHREAD_CANCEL_ENABLE 可取消属性
PTHREAD_CANCEL_DISABLE---->未决取消

线程的取消类型属性
int pthread_setcanceltype(int type, int *oldtype);

立刻被取消 PTHREAD_CANCEL_ASYNCHRONOUS

只有到达一定取消点,才会取消 PTHREAD_CANCEL_DEFERRED

读写锁

  • 如果当前线程读数据 则允许其他线程进行读操作 但不允许写操作
  • 如果当前线程写数据 则其他线程的读写都不允许操作

RCU 内核中RCU 做链表的操作

*在mutex的基础上 区分了 读锁定 和写锁定
如果某线程申请了读锁定 其他线程依旧可以申请读锁 不能申请写锁定
如果某线程申请了写锁定 则其他线程不能申请读锁定 也不能申请写锁定

pthread_rwlock_t

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr);

读锁定
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
写锁定
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

线程信号

  • 每个线程可以向其他线程发送信号 pthread_kill
  • 每个信号都有信号屏蔽集合
  • 同进程下所有线程共享对某信号的处理方法

线程信号发送

int pthread_kill(pthread_t thread, int sig);
sig -->0 向某个线程调用pthread_kill,并且第二个参数为0

int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);

SIG_BLOCK
SIG_UNBLOCK
SIG_SETMASK

不论给进程中的哪个线程发送SIG_KILL SIG_STOP 则当前进程中的所有线程都会推出

条件变量

  • 对象:pthread_cond_t condtion

  • 初始化方法:

#include <pthread.h>

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

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  • 条件变量等待
等待条件变量 
#include <pthread.h>

int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,
								const struct timespec *restrict abstime);
	int pthread_cond_wait(pthread_cond_t *restrict cond,
					pthread_mutex_t *restrict mutex);
  • 条件变量通知
通知条件变量
#include <pthread.h>

int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
  • 注意:条件变量要配合互斥体进行操作

线程的私有数据

TSD私有数据,同名但是不同内存地址的私有数据结构

  • 创建
    int pthread_key_create(pthread_key_t *key, void (destructor)(void));
    int pthread_key_delete(pthread_key_t key);

  • 读写
    void *pthread_getspecific(pthread_key_t key);
    int pthread_setspecific(pthread_key_t key, const void *value);

线程的互斥

互斥锁通信机制

  • pthread_mutex_t
  • int pthread_mutex_destroy(pthread_mutex_t *mutex);
  • int pthread_mutex_init(pthread_mutex_t *restrict mutex,
    const pthread_mutexattr_t *restrict attr);
  • int pthread_mutex_lock(pthread_mutex_t *mutex);
  • int pthread_mutex_trylock(pthread_mutex_t *mutex);
  • int pthread_mutex_unlock(pthread_mutex_t *mutex);
    %%%%%%%

pthread_self() 获得线程的tid
SYS_gettid 获得线程的tpid

通过以上的机制 我们可以更加颗粒的进行线程配合 制造出一个高效稳定的程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值