博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【多线程】零碎记录1
阅读量:7220 次
发布时间:2019-06-29

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

把自己之前几篇学习多线程知识的文章合成一篇,目的是方便离线保存。

(一)从demo开始

主要参考了下面这个视频内容()需FQ。

代码如下:

#include 
#include
#include
using namespace std;int sum = 0;void *add(void *);pthread_mutex_t mut;int main() { pthread_t thread[10]; int num; long count; cout << "Enter the number of thread bewteen (1-10): "; cin >> num; cout << "Enter number to count to: "; cin >> count; pthread_mutex_init(&mut, NULL); for ( int x=0; x

代码的功能很简单:

a. 有个一全局变量num用于累加的,每个线程都可以访问这个num

b. 向每个线程传入参数count,意义是每个线程内部对num累加多少

 

刚开始学习,不用纠结细节,先熟悉全貌。我总结需要大概了解以下几块内容,理解到哪算哪,有不到位的后面再改:

1)<pthread.h>

  含义是“Linux系统下多线程遵循POSIX接口标准”(如果是windows的话,又有另一套接口标准了)

2)pthread_create(p1, p2, p3, p4) (参照:)

函数原型:int pthread_create( pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)

 

  这是创建一个线程的函数。p2先不去管它,先看p1,p3和p4。

  p1:指向标示线程id号变量的指针(如果线程创建成功,p1指向的元素中就会被赋值一个该线程的唯一标示值)

  p3:指向线程执行的函数指针

  p4:指向传给线程参数的指针

  如果返回0:

    a. 一个新线程就run起来了

    b. 从“pthread_t *thread”指向的变量中,我们可以获得该线程的id号

    c. 甚至有可能在pthread_create返回0之前,这个新线程就执行完毕了

3)pthread_join(p1, p2) (

函数原型:int pthread_join(pthread_t thread, void **value_ptr)

  功能是wait for thread termination,在代码中的目的是让主进程等待线程执行完毕再退出

  p1:要wait的thread是谁(即线程创建时产生的唯一标示id)

  p2:暂时还没用到

到这里,其实多线程的最简单的demo就可以跑起来了。但是这里会有问题:如果若干个线程同时对全局变量num操作,就会产生资源竞争的问题。

这时候就需要一种机制来避免这样的问题,其中一种机制就成为互斥量 mutex

用法:

1)先初始化互斥量pthread_mutex_init

2)在线程内部需要加锁的代码段前pthread_mutex_lock加锁

3)在资源使用结束后pthread_mutex_unlock解锁

关于mutex是啥,下面这段话解释的很好,直接粘过来了:

  • A mutex variable acts like a "lock" protecting access to a shared data resource. The basic concept of a mutex as used in Pthreads is that only one thread can lock (or own) a mutex variable at any given time. Thus, even if several threads try to lock a mutex only one thread will be successful. No other thread can own that mutex until the owning thread unlocks that mutex. Threads must "take turns" accessing protected data.

放到这个demo中来说,mut是一个互斥量,每个线程都可以访问,但是同时只能有一个线程对其成功lock;且一旦lock上了,其他线程就不能再lock或unlock了,只能由这个线程自身unlock。

这样,保证同时只有一个线程在操作num的值,因此这个demo中就线程同步了。

同步后的输出结果:

未用mutex同步时输入的结果:

对比以上的结果:没有加入mutex每次输出的结果可能是不同的;加了mutex的代码,每次输出的结果是稳定的。

 

(二)数据线程不安全的例子

找了一个比较完备的教程:

给线程传入参数,要保证数据是线程安全的,即传入线程的参数除了能让这个线程操作之外,外部的线程不会修改。

有下面一个例子:

/** * @file 1.thread.cpp * @brief * @author xbf   xiabf11@mails.tinghua.edu.cn * @version 1.0.0 * @date 2015-08-04 */#include 
#include
#include
#define NUM_THREADS 5using namespace std;pthread_mutex_t mut;void *print(void *threadid){ pthread_mutex_lock(&mut); sleep(1); long tid; tid = *(long *)threadid; cout << "Thread " << tid << endl; pthread_mutex_unlock(&mut); pthread_exit(NULL); } int main() { pthread_t threads[NUM_THREADS]; pthread_mutex_init(&mut,NULL); for ( long t=0; t

这次给每个thread传入的是main for loop的计数变量t的引用。由于在main中每轮迭代t,所以等每个线程启动的时候访问的t就不是当时传入的t了。

这种情况就是传入线程的数据不安全。

 

转载于:https://www.cnblogs.com/xbf9xbf/p/5123949.html

你可能感兴趣的文章
redis数据类型和应用场景
查看>>
Spring IOC
查看>>
Fragment的onCreateView和onActivityCreate之间的区别(转)
查看>>
AC日记——统计难题 hdu 1251
查看>>
在仿真器中运行时跳过Windows Azure Startup任务
查看>>
android 获取路径目录方法以及判断目录是否存在,创建目录
查看>>
数列问题[HAOI2004模拟]
查看>>
2012各大IT公司校招笔试题整理
查看>>
phpcms 后台分页
查看>>
《需求工程》阅读笔记之六
查看>>
架构阅读笔记5
查看>>
IIS5.1使用虚拟目录部署网站
查看>>
Git 深度学习填坑之旅三(分支branch、远程操作)
查看>>
括号匹配问题
查看>>
UVA 10766 Organising the Organisation
查看>>
「美团 CodeM 复赛」城市网络
查看>>
python 将Excel表格中的一列数据转化成多行数据
查看>>
Go多线程与channel通信
查看>>
找水王
查看>>
多个线程之间共享数据的方式(卖票问题,存取款问题)
查看>>