博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下的线程
阅读量:6583 次
发布时间:2019-06-24

本文共 3503 字,大约阅读时间需要 11 分钟。

一、线程的优点

与传统进程相比,用线程来实现相同的功能有如下优点:

(1)系统资源消耗低。

(2)速度快。

(3)线程间的数据共享比进程间容易的多。

二、多线程编程简单实例

#include 
#include
#include
#include
voidthread1_routine(void){ printf("new thread:thread_id is %u, process_id is %u\n", pthread_self(), getpid());}voidthread2_routine(void){ printf("new thread:thread_id is %u, process_id is %u\n", pthread_self(), getpid());}intmain(void){ pthread_t pt; printf("old thread:thread_id is %u, process_id is %u\n", pthread_self(), getpid()); pthread_create(&pt, NULL, (void *)thread1_routine, NULL); pthread_create(&pt, NULL, (void *)thread2_routine, NULL); usleep(5); return(0);}

运行结果如下(可以看出在同一个进程中有三个不同的线程同时在运行):

三、线程属性

线程属性包括绑定属性、分离属性、堆栈地址、堆栈大小和优先级。其中分离属性、堆栈地址以及堆栈大小的介绍可参考。系统默认的是非邦定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。在pthread_create中,把第二个参数设置为NULL的话,将采用默认的属性配置。

1、绑定属性

线程可以分为用户级线程和内核级线程两种(可参考以及),而绑定属性正是设置用户级线程和内核级线程之间的关系。

绑定属性分为两种:绑定和非绑定。在绑定属性下,一个用户级线程固定分配给一个内核线程,因为CPU时间片的调度是面向内核线程(轻量级进程)的,因此具有 绑定属性的线程可以保证在需要的时候总有一个内核线程与之对应。在非绑定属性下,用户线程和内核线程的关系不是始终固定的,而是由系统根据实际情况分配的。

2、优先级

四、线程互斥

生产者消费者实例(多线程+互斥量):

#include 
#include
#include
void *producter_f(void *arg);void *consumer_f(void *arg);int buffer_has_item = 0;pthread_mutex_t mutex;int running = 1;int main(void){ pthread_t consumer_t; pthread_t producter_t; pthread_mutex_init(&mutex, NULL); pthread_create(&producter_t, NULL, (void *)producter_f, NULL); pthread_create(&consumer_t, NULL, (void *)consumer_f, NULL); sleep(1); /* 等待线程创建完毕 */ running = 0; pthread_join(consumer_t, NULL); pthread_join(producter_t, NULL); pthread_mutex_destroy(&mutex); return(0);}void *producter_f(void *arg){ while(running) { if(buffer_has_item < 10) /* 最多允许生产10个 */ { pthread_mutex_lock(&mutex); buffer_has_item++; printf("product, total: %d\n", buffer_has_item); pthread_mutex_unlock(&mutex); } }}void *consumer_f(void *arg){ while(running) { if(buffer_has_item > 0) /* 缓冲区为空时不允许再消费 */ { pthread_mutex_lock(&mutex); buffer_has_item--; printf("consume, total: %d\n", buffer_has_item); pthread_mutex_unlock(&mutex); } }}

编译运行结果如下:

 

五、线程中使用信号量

(此处使用的信号量是POSIX无名信号量:)

线程的信号量与进程的信号量类似,使用线程的信号量可以高效地完成基于线程的资源计数。信号量实际上是一个非负的整数计数器,用来实现对公共资源的控制。在公共资源增加的时候,信号量的值增加;公共资源消耗的时候,信号量的值减少;只有当信号量的值大于0时,才能允许访问信号量所代表的公共资源。

生产者消费者实例(多线程+信号量):

#include 
#include
#include
void *producter_f(void *arg);void *consumer_f(void *arg);sem_t sem;int running = 1;int main(void){ pthread_t consumer_t; pthread_t producter_t; sem_init(&sem, 0, 16); pthread_create(&producter_t, NULL, (void *)producter_f, NULL); pthread_create(&consumer_t, NULL, (void *)consumer_f, NULL); sleep(1); running = 0; pthread_join(consumer_t, NULL); pthread_join(producter_t, NULL); sem_destroy(&sem); return(0);}void *producter_f(void *arg){ int semval = 0; while(running) { usleep(1); sem_post(&sem); sem_getvalue(&sem, &semval); printf("product, total: %d\n", semval); }}void *consumer_f(void *arg){ int semval = 0; while(running) { usleep(1); sem_wait(&sem); sem_getvalue(&sem, &semval); printf("consume, total: %d\n", semval); }}
编译运行如下:

 

更多关于线程的介绍可参考及其后续博文。

转载地址:http://huxno.baihongyu.com/

你可能感兴趣的文章
代码片段
查看>>
软工第二周个人作业
查看>>
不固定个数组,进行一一对应的组合,js将多个数组实现排列组合
查看>>
一个陌生女人的来信
查看>>
SqlServer和Oracle临时表生命周期
查看>>
jquery判断文本框输入的是非数字内容(交流QQ群:452892873)
查看>>
为知笔记-艾宾浩斯遗忘曲线复习插件
查看>>
20050616:今天跟老外第一次讲E文,我说:
查看>>
实验三—单臂路由
查看>>
Python之定义函数
查看>>
Linux下编译安装PHP7.2
查看>>
使用vue如何默认选中单选框
查看>>
pageContext.request.contextPath} JSP取得绝对路径
查看>>
毕业设计进度日志02
查看>>
linux配置java环境变量
查看>>
cocos2d-x遍历zip某个目录(可用于android中apk包的文件访问)
查看>>
IO中同步与异步,阻塞与非阻塞区别(转)
查看>>
数据库升级层
查看>>
css之postion定位
查看>>
补第一阶段冲刺站立会议2(应发表日期5月14日)
查看>>