[转]c++ pthread 多线程简介
链接:https://blog.csdn.net/u013894427/article/details/83827173
pthread 入口函数类型说明
void * func1(void * t)
void* 表示无类型指针
void*作为函数参数,表示函数接收一个指针,不管是什么类型的指针都可以,但是传递之前要强制转换为无类型指针。
基础流程
pthread_t t1;//声明一个线程
pthread_create(&t1, NULL, &test, (void *)this);//创建一个线程
pthread_exit(NULL);//退出线程
pthread_create()
函数原型
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
含有四个参数,
第一个参数表示线程id
第二个参数表示线程参数
第三个是线程的入口函数名字
第四个参数表示线程入口函数的参数名字
pthread_exit();
函数原型
void pthread_exit(void *retval)
写在线程内部,用于强制退出当前线程
如果线程是joinable,可以在函数参数里面传递线程的退出信息给主线程
例如
#include <pthread.h>
#include <iostream>
using namespace std;
void *thread1(void *);
int status;
int main(void)
{
void *status_m;
cout << "status_m addr is " << &status_m << endl;
pthread_t t_a;
pthread_create(&t_a,NULL,thread1,NULL);/*创建进程t_a*/
pthread_join(t_a, &status_m);/*等待进程t_a结束*/
cout << "status_m value is " << status_m << endl;
int * re=(int *)status_m;
cout << "the value is " << *re << endl;
return 0;
}
void *thread1(void *junk)
{
status=23333;
cout << "status addr is " << &status << endl;
pthread_exit((void *)&status);
}
可以打印出
status_m addr is 0x7ffe3cfd6170
status addr is 0x6021b4
status_m value is 0x6021b4
the value is 23333
线程的joinable和detached属性
属性的设置方法如下
pthread_attr_t attr;//声明一个参数
pthread_attr_init(&attr);//对参数进行初始化
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);//设置线程为可连接的
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//设置线程为可分离的
pthread_attr_destroy(&attr)//销毁属性,防止内存泄漏
属性的相关操作如下:
pthread_detach()
函数原型
int pthread_detach(pthread_t tid);
1
detached的线程在结束的时候会自动释放线程所占用的资源
pthread_join()
函数原型
int pthread_join(pthread_t tid, void **status);
joinable的线程必须用pthread_join()函数来释放线程所占用的资源,如果没有执行这个函数,那么线程的资源永远得不到释放。
互斥锁 mutex
互斥锁是为了多个线程在运行过程中保持数据同步引入的机制。
基本流程
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
pthread_mutex_init(&mutex,NULL);/*动态初始化互斥锁*/
pthread_mutex_lock(&mutex);//加锁
pthread_mutex_unlock(&mutex);//解锁
pthread_mutex_destroy(&mutex);//销毁互斥锁
举个例子
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
pthread_mutex_t mutex ;
void *print_msg(void *arg){
int i=0;
pthread_mutex_lock(&mutex);
for(i=0;i<15;i++){
printf("output : %d\n",i);
usleep(100);
}
pthread_mutex_unlock(&mutex);
}
int main(int argc,char** argv){
pthread_t id1;
pthread_t id2;
pthread_mutex_init(&mutex,NULL);
pthread_create(&id1,NULL,print_msg,NULL);
pthread_create(&id2,NULL,print_msg,NULL);
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_mutex_destroy(&mutex);
return 1;
}
条件变量
基本流程
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/
pthread_mutex_lock(&mutex);/*锁住互斥量*/
pthread_cond_signal(&cond);//发送信号量 跟wait函数不在同一个线程中
pthread_cond_wait(&cond,&mutex);//阻塞线程,等待条件变量,同时解锁互斥量
pthread_mutex_unlock(&mutex);//解锁互斥量
pthread_mutex_destroy(&mutex);//销毁互斥锁
pthread_cond_destroy(&cond);//销毁条件变量
举个例子
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/
void *thread1(void *);
void *thread2(void *);
int i=1;
int main(void)
{
pthread_t t_a;
pthread_t t_b;
pthread_create(&t_a,NULL,thread1,(void *)NULL);/*创建进程t_a*/
pthread_create(&t_b,NULL,thread2,(void *)NULL); /*创建进程t_b*/
pthread_join(t_a, NULL);/*等待进程t_a结束*/
pthread_join(t_b, NULL);/*等待进程t_b结束*/
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
exit(0);
}
void *thread1(void *junk)
{
for(i=1;i<=6;i++)
{
printf("thread1: Line: %d, i = %d\n", __LINE__, i);
pthread_mutex_lock(&mutex);/*锁住互斥量*/
printf("thread1: lock %d\n", __LINE__);
if(i%3==0)
{
printf("thread1:signal 1 %d\n", __LINE__);
pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b进程*/
printf("thread1:signal 2 %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n", __FUNCTION__, __LINE__);
sleep(1);
}
pthread_mutex_unlock(&mutex);/*解锁互斥量*/
printf("thread1: unlock %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n\n", __FUNCTION__, __LINE__);
sleep(1);
}
}
void *thread2(void *junk)
{
while(i<6)
{
printf("thread2: Line: %d, i = %d\n", __LINE__, i);
pthread_mutex_lock(&mutex);
printf("thread2: lock %d\n", __LINE__);
if(i%3!=0)
{
printf("thread2: wait 1 %d\n", __LINE__);
pthread_cond_wait(&cond,&mutex);/*解锁mutex,并等待cond改变*/
printf("thread2: wait 2 %d\n", __LINE__);
}
pthread_mutex_unlock(&mutex);
printf("thread2: unlock %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n\n", __FUNCTION__, __LINE__);
sleep(1);
}
}
结果为:
thread1: Line: 29, i = 1
thread1: lock 31
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread2: Line: 52, i = 1
thread2: lock 54
thread2: wait 1 57
thread1: Line: 29, i = 2
thread1: lock 31
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread1: Line: 29, i = 3
thread1: lock 31
thread1:signal 1 34
thread1:signal 2 36
thread1 will sleep 1s in Line: 37
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread2: wait 2 59
thread2: unlock 62
thread2 will sleep 1s in Line: 63
thread1: Line: 29, i = 4
thread1: lock 31
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread2: Line: 52, i = 4
thread2: lock 54
thread2: wait 1 57
thread1: Line: 29, i = 5
thread1: lock 31
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread1: Line: 29, i = 6
thread1: lock 31
thread1:signal 1 34
thread1:signal 2 36
thread1 will sleep 1s in Line: 37
thread1: unlock 41
thread2: wait 2 59
thread2: unlock 62
thread2 will sleep 1s in Line: 63
thread1 will sleep 1s in Line: 42
注意:thread2 wait 1和thread2 wait 2的位置可以知道wait函数在执行的时候会阻塞thread2,并且解锁互斥量
[转]c++ pthread 多线程简介的更多相关文章
- pthread多线程编程的学习小结
pthread多线程编程的学习小结 pthread 同步3种方法: 1 mutex 2 条件变量 3 读写锁:支持多个线程同时读,或者一个线程写 程序员必上的开发者服务平台 —— DevSt ...
- VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程 转载
VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程 转载 #include <stdio.h>#include &l ...
- iOS开发多线程篇—多线程简介
iOS开发多线程篇-多线程简介 一.进程和线程 1.什么是进程 进程是指在系统中正在执行的一个应用程序 每一个进程之间是独立的.每一个进程均执行在其专用且受保护的内存空间内 比方同一时候打开QQ.Xc ...
- 多线程简介及GCD的使用
多线程简介: 对于任意一个iOS应用,程序运行起来后,默认会产生一个主线程(MainThread),主线程专门用来处理UIKit对象的操作,如界面的显示与更新.处理用户事件触发的操作等等.(记忆这点, ...
- Java多线程简介
Java多线程简介 Java中内置了对多线程的支持,让多线程的开发方便很多,但同时也带来了另外的复杂,线程间的交互以及很多的不确定性让多线程又显得很复杂.在此只是针对Java中多线程的基础做些说明,有 ...
- C语言使用pthread多线程编程(windows系统)二
我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我 ...
- clone的fork与pthread_create创建线程有何不同&pthread多线程编程的学习小结(转)
进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合,这些资源在Linux中被抽 象成各种数据对象:进程控制块.虚存空间.文件系统,文件I/O.信号处理函数.所以创建一个进程的 过程就是这 ...
- NDK中使用pthread多线程中自己写的一个BUG
在使用pthread进行NDK中的多线程开发时,自己写了一个BUG, void *darkGrayThread(void *args) { ThreadParam *param = (ThreadPa ...
- php Pthread 多线程基本介绍
我们可以通过安装Pthread扩展来让PHP支持多线程. 线程,有时称为轻量级进程,是程序执行的最小单元.线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,它与同属 ...
随机推荐
- Zabbix Documentation 4.0
Zabbix Documentation 4.0 1 Create user account For all of the Zabbix daemon processes, an unprivileg ...
- git指令集合
原网页:https://www.linuxidc.com/Linux/2018-04/151809.htm Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文 ...
- go语言笔记1
Go语言学习整理 本文基于菜鸟教程,对于自己不明白的点加了点个人注解,对于已明确的点做了删除,可能结构不太清晰,看官们可移步Go语言教程 1 Go语言结构当标识符(包括常量.变量.类型.函数名. ...
- 微信小程序~页面注册page
一 什么是page() page(),是一个函数,用来注册一个页面, 接受一个object参数, 指定页面的初始数据,生命周期函数,事件处理函数 等等 object参数说明: (1)data (obj ...
- 微信小程序~项目步骤和流程
从运营的角度讲制作,不是从程序的角度讲开发,所以简单明晰,通俗易懂,小白也能按照流程完成制作. 微信小程序制作步骤及流程 1.确定好微信小程序的的定位和目的 如行业,功能,内容,目标用户,目标市场,意 ...
- python练习题(四)
题目: 根据一个字符串返回一个ip数组,按照ip最后一位排序, 字符串: str = 'ss192.0.0.12?!289.0.0.1!0.0.0.0!192.163.10.28?192.0.0.5' ...
- 第三方登录绑定csrf漏洞利用
作者:pmiaowu 文章:https://www.yuque.com/pmiaowu/web_security_1/sq87w6 这里需要使用到一个微博账号与两个某厂商账号 条件: 1.微博账号:1 ...
- Pivotal Greenplum 6.0 新特性介绍
Pivotal Greenplum 6.0 新特性介绍 在1月12日举办的Greenplum开源有道智数未来技术研讨会上,Pivotal中国研发中心Greenplum 产品经理李阳向大家介绍了Pi ...
- rust cargo 一些方便的三方cargo 子命令扩展
内容来自cargo 的github wiki,记录下,方便使用 可选的列表 cargo-audit - Audit Cargo.lock for crates with security vulner ...
- 使用gitbase 分析git 仓库代码
gitbase 是一个基于golang 开发的开源git 仓库sql 接口查询引擎,基于此工具,我们可以方便的分析git 仓库代码的情况 而且可以基于源码的分析,还是很强大的 安装 直接使用编译的 ...