当前位置:网站首页 > 技术博客 > 正文

pthread线程间通信



线程按照其调度者可以分为用户级线程和核心级线程两种
用户级线程主要解决的是上下文切换的问题,它的调度算法和调度过程全部由用户自行选择决定,在运行时不需要特定的内核支持;
我们常用基本就是用户级线程,所以就只总结一下POSIX提供的用户级线程接口;
基本线程操作相关的函数:
1线程的建立结束
2线程的互斥和同步
3使用信号量控制线程
4线程的基本属性配置

基本线程操作:

函数说明 pthread_create() 创建线程开始运行相关线程函数,运行结束则线程退出 pthread_eixt() 因为exit()是用来结束进程的,所以则需要使用特定结束线程的函数 pthread_join() 挂起当前线程,用于阻塞式地等待线程结束,如果线程已结束则立即返回,0=成功 pthread_cancel() 发送终止信号给thread线程,成功返回0,但是成功并不意味着thread会终止 pthread_testcancel() 在不包含取消点,但是又需要取消点的地方创建一个取消点,以便在一个没有包含取消点的执行代码线程中响应取消请求. pthread_setcancelstate() 设置本线程对Cancel信号的反应 pthread_setcanceltype() 设置取消状态 继续运行至下一个取消点再退出或者是立即执行取消动作 pthread_setcancel() 设置取消状态
函数说明 pthread_mutex_init() 互斥锁的初始化 pthread_mutex_lock() 锁定互斥锁,如果尝试锁定已经被上锁的互斥锁则阻塞至可用为止 pthread_mutex_trylock() 非阻塞的锁定互斥锁 pthread_mutex_unlock() 释放互斥锁 pthread_mutex_destory() 互斥锁销毁函数
函数说明 sem_init(sem) 初始化一个定位在sem的匿名信号量 sem_wait() 把信号量减1操作,如果信号量的当前值为0则进入阻塞,为原子操作 sem_trywait() 如果信号量的当前值为0则返回错误而不是阻塞调用(errno=EAGAIN),其实是sem_wait()的非阻塞版本 sem_post() 给信号量的值加1,它是一个“原子操作”,即同时对同一个信号量做加1,操作的两个线程是不会冲突的 sem_getvalue(sval) 把sem指向的信号量当前值放置在sval指向的整数上 sem_destory(sem) 销毁由sem指向的匿名信号量
函数说明 pthread_attr_init() 初始化配置一个线程对象的属性,需要用pthread_attr_destroy函数去除已有属性 pthread_attr_setscope() 设置线程属性 pthread_attr_setschedparam() 设置线程优先级 pthread_attr_getschedparam() 获取线程优先级

例程中循环3次建立3条线程,并且使用pthread_join函数依次等待线程结束;
线程中使用rand()获取随机值随机休眠5次,随意会出现后执行的线程先执行完成;
运行结果:

可以看到,线程1先于线程0执行,但是pthread_join的调用时间顺序,先等待线程0执行;
由于线程1已经早结束,所以线程0被pthread_join等到的时候,线程1已结束,就在等待到线程1时,直接返回;

在上面的程序中增加互斥锁

在上面的例程中直接添加同步锁pthread_mutex_t;
在线程中加入,于是程序在执行线程程序时;
调用pthread_mutex_lock上锁,发现上锁时候后进入等待,等待锁再次释放后重新上锁;
所以线程程序加载到队列中等待,等待成功上锁后继续执行程序代码;
运行结果

跟例程1中执行结果不同,线程程序被加载到队列中而不能马上执行,需要等到能够成功上锁;
上锁后,继续执行线程程序,上锁执行;
这样线程被依次执行的情况在实际使用场景中经常出现;
使用场景:
当用户登录后获取秘钥才能继续获取该用户的基本信息时;需要等待登录线程结束后才能继续执行获取用户信息的线程时,
需要调用两条线程,假如是:threadLogin(),threadGetInfo(); 则可以有2种方法实现:
1 此时可以使用互斥锁同时一次性调用完threadLogin()和threadGetInfo();
2 当然也可以不使用互斥锁直接在threadLogin()中登录验证成功后调用threadGetInfo();
相比之下,方式1更加清晰的显示逻辑关系,增加代码可读性可扩展性。

执行结果,仍然是建立3条线程,每条线程执行时休眠随机时长:

设置属性一般有:
1 绑定属性
2 分离属性
3 堆栈地址
4 堆栈大小
5 优先级

在运行前后使用 $ free 命令查看内存前后的使用情况发现:
在线程结束后内存马上被释放;
其实,一般线程的属性直接使用系统默认属性即可;
关于线程的使用,大约就是这样。

版权声明


相关文章:

  • 软件开发平台有哪些2025-03-29 07:29:59
  • 备忘录ui设计2025-03-29 07:29:59
  • 共享内存和socket2025-03-29 07:29:59
  • 浏览器性能测试工具2025-03-29 07:29:59
  • 路由交换技术入门2025-03-29 07:29:59
  • opencv颜色分类2025-03-29 07:29:59
  • jmap 分析内存2025-03-29 07:29:59
  • 思科模拟器三层交换机2025-03-29 07:29:59
  • typeof和instance of2025-03-29 07:29:59
  • unicode和utf8的关系2025-03-29 07:29:59