Linux下c++多线程和互斥锁
2016-07-01 11:43
591 查看
一、多线程
多线程使用的是pthread库,写程序的时候需要引入头文件pthread.h, g++编译的时候需要加上该库的依赖“-lpthread”。
1 先看程序便于理解,代码下面有对注释的解释。下面的代码含义是创建两个线程,一个线程去计算某个变量的阶乘,另一个去计算从0到某个变量的和
输出:
thread1 get fact:3628800
thread2 get sum:55
2 对上面的函数的解析
注释1
首先声明函数,该函数是创建的线程要执行的函数,注意里面的参数,是无类型的指针
注释2
线程要根据线程ID区分,改变量用于保存线程的ID
注释3:
pthread_create()原型:
extern int pthread_create (pthread_t *__restrict __newthread,
const pthread_attr_t *__restrict __attr,
void (*__start_routine) (void ),
void *__restrict __arg) __THROWNL __nonnull ((1, 3));
包含四个参数如下
__newthread: 如果创建成功,改变量保存创建成功的线程ID
__attr: 传递线程属性参数,传递NULL时创建默认属性的线程
__start_routine: 相当于线程的main函数,创建好的线程执行该函数
__arg: 要传递给线程执行函数的参数,它其实是一个变量的地址,不传递参数时可以设置为NULL
该函数如果执行成功,则返回0,执行失败返回其他值
注释4
大家可以先把这行代码去掉看看效果,会发现可能没有任何输出,这并不是错误。这是由于main函数执行完毕即可结束,没有等待我们创建的线程结束。所以pthread_join(t_fact, NULL);的含义就是等待t_fact这个线程结束后,main函数才会结束。
注释5
如上面所说,传递过来的参数是一个无类型的指针,我们需要将其转换为我们需要的数据。
二、互斥锁
涉及到多线程必然会有互斥问题,上面的代码没有访问冲突,但是加入有两个线程一个将其增1,一个将其减1,这样如果没有互斥访问就可能存在错误。同上,先上代码便于理解,注释会在下文给出。
1 下面的代码含义是两个进程对某个bool变量互斥访问,此处不再解释多线程的问题,只解释互斥锁的写法
2 对上面注释的解释
注释1
定义一个互斥变量
注释2
将互斥变量初始化
注释3
结束后将互斥量销毁
注释4
申请该互斥锁,申请到的话可以执行下面的代码,申请失败则会阻塞,只能有一个线程可以申请到。
注释5
线程结束访问后释放互斥锁,可以让其他线程申请该锁。
补充:上面两个只是简单的介绍,还有其他原理和其他用法由于本人水平所限没有介绍,后期再慢慢更新,如有错误或者建议可以留言。
多线程使用的是pthread库,写程序的时候需要引入头文件pthread.h, g++编译的时候需要加上该库的依赖“-lpthread”。
1 先看程序便于理解,代码下面有对注释的解释。下面的代码含义是创建两个线程,一个线程去计算某个变量的阶乘,另一个去计算从0到某个变量的和
#include <iostream> #include <pthread.h> #include <string.h> void *thread1_fact(void *arg); // 注释1 void *thread2_sum(void *arg); int main() { pthread_t t_fact; // 注释2 pthread_t t_sum; int i = 10; if (pthread_create(&t_fact, NULL, thread1_fact, &i) != 0) { // 注释3 std::cout << "pthread_create() error"; return -1; } if (pthread_create(&t_sum, NULL, thread2_sum, &i) != 0) { std::cout << "pthread_create() error"; return -1; } pthread_join(t_fact, NULL); // 注释4 pthread_join(t_sum, NULL); return 0; } void *thread1_fact(void *arg) { int i = *(int*)arg; //注释5 int fact = 1; while(i){ fact *= i; i--; } std::cout << "thread1 get fact:" << fact << std::endl; } void *thread2_sum(void *arg) { int i = *(int*)arg; int sum = 0; while (i>0) { sum += i; i--; } std::cout << "thread2 get sum:" << sum << std::endl; }
输出:
thread1 get fact:3628800
thread2 get sum:55
2 对上面的函数的解析
注释1
首先声明函数,该函数是创建的线程要执行的函数,注意里面的参数,是无类型的指针
注释2
线程要根据线程ID区分,改变量用于保存线程的ID
注释3:
pthread_create()原型:
extern int pthread_create (pthread_t *__restrict __newthread,
const pthread_attr_t *__restrict __attr,
void (*__start_routine) (void ),
void *__restrict __arg) __THROWNL __nonnull ((1, 3));
包含四个参数如下
__newthread: 如果创建成功,改变量保存创建成功的线程ID
__attr: 传递线程属性参数,传递NULL时创建默认属性的线程
__start_routine: 相当于线程的main函数,创建好的线程执行该函数
__arg: 要传递给线程执行函数的参数,它其实是一个变量的地址,不传递参数时可以设置为NULL
该函数如果执行成功,则返回0,执行失败返回其他值
注释4
大家可以先把这行代码去掉看看效果,会发现可能没有任何输出,这并不是错误。这是由于main函数执行完毕即可结束,没有等待我们创建的线程结束。所以pthread_join(t_fact, NULL);的含义就是等待t_fact这个线程结束后,main函数才会结束。
注释5
如上面所说,传递过来的参数是一个无类型的指针,我们需要将其转换为我们需要的数据。
二、互斥锁
涉及到多线程必然会有互斥问题,上面的代码没有访问冲突,但是加入有两个线程一个将其增1,一个将其减1,这样如果没有互斥访问就可能存在错误。同上,先上代码便于理解,注释会在下文给出。
1 下面的代码含义是两个进程对某个bool变量互斥访问,此处不再解释多线程的问题,只解释互斥锁的写法
#include <iostream> #include <netinet/in.h> #include <pthread.h> void *thread_write(void *arg); pthread_mutex_t mutex; // 注释1 int main() { pthread_mutex_init(&mutex, NULL); //注释2 pthread_t t_1; pthread_t t_2; if (pthread_create(&t_1, NULL, thread_write, NULL) != 0) { std::cout << "pthread_create() error"; return -1; } if (pthread_create(&t_2, NULL, thread_write, NULL) != 0) { std::cout << "pthread_create() error"; return -1; } pthread_join(t_1, NULL); pthread_join(t_2, NULL); pthread_mutex_destroy(&mutex); //注释3 return 0; } void *thread_write(void *arg) { pthread_mutex_lock(&mutex); //注释4 std::cout << "one apply for the mutex successfully" << std::endl; pthread_mutex_unlock(&mutex); //注释5 }
2 对上面注释的解释
注释1
定义一个互斥变量
注释2
将互斥变量初始化
注释3
结束后将互斥量销毁
注释4
申请该互斥锁,申请到的话可以执行下面的代码,申请失败则会阻塞,只能有一个线程可以申请到。
注释5
线程结束访问后释放互斥锁,可以让其他线程申请该锁。
补充:上面两个只是简单的介绍,还有其他原理和其他用法由于本人水平所限没有介绍,后期再慢慢更新,如有错误或者建议可以留言。
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- Linux 下无损图片压缩小工具介绍