您的位置:首页 > 运维架构 > Linux

Linux下c++多线程和互斥锁

2016-07-01 11:43 591 查看
一、多线程

多线程使用的是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 pthread多线程