线程掌握这几个简单基础用法

多线程编程的好处:

  1. 处理不同的异步事件时可以为每个事件处理时分配单独的处理线程,每个线程在进行事件处理时可以采用同步编程模式。
  2. 采用多个线程可以访问相同的存储地址空间和文件描述符。
  3. 提高程序的吞吐量,多个线程可以使相互独立的任务交叉运行,提高CPU使用率。
  4. 多线程可以处理用户输入输出的部分和其它部分分开,改善响应时间。

线程标识:

和进程ID一样,线程也有一个线程ID,只不过是在该进程中是唯一的,为了可移植性,可以使用系统提供的接口进行两个线程ID比较

#include <pthread.h>
int pthread_equal(pthread_t tid1, pthread_t tid2);
//返回值:若相等,返回非0数值;否则,返回0

pthread_t pthread_self(void);
//返回值:调用线程的线程ID

线程的创建

int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//返回值:若成功,返回0;否则,返回错误编号
//tidp:新创建线程的线程ID会存储在tidp指向的内存单元
//attr:设置各种不同的属性,设置为NULL,表示使用默认属性
//start_rtn:函数指针,参数和返回值均为无类型指针
//arg:为start_rtn函数的参数

线程终止

线程退出有四种方式:

  1. 终止整个进程,线程可以调用exit,_Exit或者_exit
  2. 线程可以直接调用return返回,返回值是线程的退出码
  3. 线程可以被同一进程中的其它线程取消
  4. 线程调用pthread_exit
int pthread_exit(void *rval_ptr);
//rval_ptr是一个无类型指针,同一进程的其它线程可以调用pthread_join函数访问到这个指针
int pthread_join(pthread_t thread, void **rval_ptr);
//返回值:若成功,返回0;否则,返回错误编号
//调用的线程将一直阻塞,知道指定的线程终止

注意:使用pthread_create和pthread_exit函数的无类型指针参数必须是调用完成后是有效的,如果是在栈上分配了该结构,那么其它的线程调用在使用这个结构时内存内容可能已经改变

int pthread_cancel(pthread_t tid);
//该函数并不等待线程终止,它仅仅提出请求
//返回值:若成功,返回0;否则,返回错误编号

线程清理函数

void pthread_cleanup_push(void (*rtn) (void *), void *arg);
void pthread_cleanup_pop(int execute);
//当线程执行以下动作时,清理函数rtn会被pthread_cleanup_push函数调度
//1.调用pthread_exit时;
//2.响应取消请求pthread_cancel时
//3.用非零execute函数调用pthread_cleanup_pop时

线程分离

int pthread_detach(pthread_t tid);
//返回值:若成功,返回0;否则,返回错误编号
//如果线程已经被分离,线程的底层存储资源可以在线程终止时立即被回收,不能使用pthread_join函数等待它的终止状态,因为会产生未定义行为

线程同步

为什么需要线程同步?
当一个线程可以修改的变量,其它线程也可以读取或者修改的时候,在存储器读与存储器写这两个周期交叉时,这种不一致就会出现,又或者两个线程同时都在写,写的步骤通常分为3步,从内存单元读入寄存器,在寄存器中对变量做增量操作,把新的值写回内存单元,很有可能两个线程对同一个变量操作是交叉进行的,故而出现和预期结果不一样的情况。

互斥量

int pthread_mutex_init(pthread_metex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread__mutex_t *mutex);
//两个函数的返回值:若成功,返回0;否则,返回错误编号
//如果动态分配互斥量,在释放内存前需要调用pthread_mutex_destroy
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t * mutex);
//尝试对互斥量加锁,不能锁住互斥量时返回EBUSY,否则返回0
int pthread_mutex_unlock(pthread_mutex_t *mutex);

自旋锁和互斥量类似,但它不是通过休眠使线程休眠,而是在获取锁之前一直处于忙等(自旋)阻塞状态,自旋锁可以用作以下情况,锁被持有的时间短,而且线程并不希望在重新调度上花费太多的成本,当然除了互斥量和自旋锁外还有,屏障,读写锁,条件变量均可以实现同步,不过这几种使用的比较少。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值