Lecture 3 (6D-8A): 共享内存编程--Pthre
2020-11-08 本文已影响0人
Catherin_gao
一. 共享内存编程
1. 多线程容易遇到的问题
- 同步:不同线程间的数据保持相同。
- 死锁:线程间数据互相依赖而互相等待。
- Cache 一致性:不同core之间的数据一致性。
2. 多线程可以通过哪些方式实现:
- 多线程编译器:OpenMP
- Unix processes
- Thread: pthread
3. Process和thread的区别
- Thread有一些memory content是可以共享的。
- Linux的process 和thread 几乎没有区别。但是Linux可以通过FLAG定义哪些内容进行共享。
pthread_creat(&thread1,NULL,func1,&arg);
pthread_join(thread1,*status);
func(&arg){
.
.
.
return(*status)
}
二. Pthread
4. pthread的例子
- pthread传输的是void类型,只能在程序内部cast。
- pthread 只是生成线程,怎么沟通和控制需要自己通过memory进行。
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadld){
long* data = static_cast<long*> threadld;
printf("Hello World! thread #%ld!\n", *data);
pthread_exit(NULL);
}
int main(int argc, char *argv[]){
pthread_t threads[NUM_THREADS];
for(long tid=0;tid<NUM_THREADS;tid++){
pthread_create(&threads[tid],NULL,PrintHello,(void*)&tid);
}
pthread_exit(NULL);
}
5. Pthread Joining & Detaching
-
join和detach必须二选一。
-
pthread_join(threadId, status)
- 一直等到特殊的threadId 线程结束,拿到特殊thread的返回值。
- 线程间同步
-
pthread_detach(threadId)
- 一旦一个线程detached,就永远不可能joined
- detach a thread 会释放一些系统资源。
6. 同步问题
- 寄存器初始值为5:
producer: move ax, counter -> ax=5
producer: add ax, 1 -> ax=6
context switch
consumer: move bx, counter ->bx =5
consumer: sub bx, 1 ->bx =4
context switch
producer: move counter, ax -> counter =6
context switch
consumer: move counter, bx ->counter =4
- conter的值有可能是4,或6,或5
- 正确的值应该是5.
6.1 Pthread
- Critical Section 临界区
- 这段代码只能同时被一个process/thread介入。
- Mutual exclusion 互斥
- 保证只有一个process/thread 可以在in a critical section
- Lock: 一种简单的实现方式去保证临界区的互斥。
while (lock == 1); lock = 1;
.
critical section
. lock = 0;
/* no operation in while loop */ /* enter critical section */
/* leave critical section */
Pthread Lock/ Mutex Routines
- “mutex” 是Pthreads 实现lock的变量
- 最重要的是需要自己判断哪段代码是shared_memory,把这段代码放入互斥区。
- mutex的变量类型:pthread_mutex_t
- pthread_mutex_init()
- mutex必须销毁:pthread_mutex_detroy()
- 临界区 可以被两个函数保护:
- pthread_mutex_lock(&mutex);
- pthread_mutex_unlock(&mutex);
#include "pthread.h"
pthraed_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
pthread_mutex_lock(&mutex);
Critical Section
pthread_mutex_unlock(&mutex);
pthread_mutex_detroy(&mutex);
Bounded-buffer Problem
-
一个有n 个buffer的池子,每个buffer保存一个元素。
-
Producer 生产者:
- 找到一千个空的buffer
- 写入一个元素到buffer中
- 如果没有空的buffer,等待
-
Consumer
- 找到一个buffer并收回空间
- 把buffer放回到free pool中
- 如果所有buffer是空的,等待。
Condition Variable (CV)
- CV 代表一些condition: