C++ 并行与分布式编程 chapter5 任务间并发的同步(1)
2010-11-19 19:38
447 查看
任务间并发的同步
同步任务之间的关系开始-开始关系(SS) 虚拟人(avatar)的嘴巴和声音同时执行
结束-开始关系(FS) 任务A不能结束直至任务B开始运行类似于父子进程,父进程产生一个子进程或者父进程从子进程接收到子进程已经开始运行的通信之前,父进程不能完全执行某些操作。
开始-结束关系(SF) 一个任务不能开始,直至另一个任务结束,在管道中读取数据
结束-结束关系(FF) 任务B结束之前,任务A不能结束。父进程必须等待子进程终止之后才能终止
同步数据的访问进程间共享数据的一种方法就是创建一个存储器块,然后将这个存储器块映射到需要共享该数据的进程的地址空间中;另一种方法就是在两个进程的地址空间外创建一个存储器块。IPC(Inter Process Communication)包括:管道、文件、和消息传递。在一个多线程环境中,必须对共享存储器、全局变量和文件的并发访问进行同步。临界区(Critical Section)是可以改变文件指针位置、写文件、关闭文件和读写全局变量或数据结构的任何代码块。
信号量信号量(semaphore)是管理同步关系和实现访问策略的一种同步机制。仅能被某些特定的操作访问。作为资源访问的关键字,这个关键字在某一时刻只能由一个进程或线程拥有。不管那个任务拥有该关键字,那么这个任务就对资源加锁,并独自使用这个资源。
P()是减少操作lock,V()增加操作unlock
P(Mutex)
if(Mutex > 0) {
Mutex--;
}
else {
Block on Mutex;
}
V(Mutex)
if(Blocked on Mutex N processes) {
pass on Mutex;
}
else{
Mutex++;
}
这两个操作的实现依赖于系统。信号量有几类:二进制信号量只有值0或1;计数信号量:一些非负的整数值。POSIX(Portable Operating System UNIX)定义了几种信号量。
1.互斥锁信号量 实现代码临界区互斥机制,通过串行化对临界区的访问来避免竞争的产生。基本操作
pthread_mutex_t Functions Mutex Operations
Function Prototypes/Macros #include <pthread.h>
Initialization
int pthread_mutex_init(pthread_mutex_t *restrict
mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
Request ownership
<time.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_timedlock(pthread_mutex_t
*restrict mutex, const struct tiemspec *restrict
abs_timeout);
Release ownership
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Try ownership
int pthread_mutex_trylock(pthread_mutex_t *mutex);
Destruction
int pthread_mutex_destroy(pthread_mutex_t *mutex);
互斥锁有一个属性对象,传递给初始化函数,创建一个互斥锁,如果采用缺省属性可以使用宏pthread_mutext Mutex = PTHREAD_MUTEX_INITIALIZER;这种方法开销较小,但是不执行任何错误检查。
一个互斥锁可以是专有或共有的。请求所有权操作将互斥锁的所有权授予调用它的进程或线程。一旦互斥锁已经是专有的,那么线程或进程就可以对资源进行访问。如果其他进程或线程试图拥有互斥锁,这些进程或线程就会被阻塞,直到互斥锁可以利用。Try ownership用来测试一个互斥锁是否是专有的(owned),如果互斥锁是专有的,调用这个函数的进程或线程不会被阻塞,如果互斥锁是共有的(unowned),就授予该进程或线程专有权。如果存储器是专有或这有线程在等待这个互斥锁,那么存储器就不能被释放或者关闭(Destruction)。互斥锁实现EREW互斥读和互斥写
互斥锁属性对象的使用方法和线程属性对象的使用方法类似。封装互斥锁对象的所有属性。私有的互斥锁只能在相同的进程中的线程间共享;共享的互斥锁可以由对互斥锁所在存储器位置进行访问的任何线程使用,包括其他进程中的线程。
// ...
pthread_t ThreadA,ThreadB;
pthread_mutex_t Mutex;
pthread_mutexattr_t MutexAttr;
void *task1(void *X)
{
pthread_mutex_lock(&Mutex);
// critical section of code
pthread_mutex_unlock(&Mutex);
return(0);
}
void *task2(void *X)
{
pthread_mutex_lock(&Mutex);
// critical section of code
pthread_mutex_unlock(&Mutex);
return(0);
}
int main(void)
{
//...
pthread_mutexattr_init(&MutexAttr);
pthread_mutex_init(&Mutex,&MutexAttr);
//set mutex attributes
pthread_create(&ThreadA,NULL,task1,NULL);
pthread_create(&ThreadB,NULL,task2,NULL);
//...
return(0);
}
int Rt;
pthread_mutex_t Mutex1;
pthread_mutexattr_t MutexAttr;
int main(void)
{
//...
pthread_mutexattr_init(&MutexAttr);
pthread_mutexattr_setpshared(&MutexAttr,
PTHREAD_PROCESS_SHARED);//初始化为共享
pthread_mutex_init(&Mutex1,&MutexAttr);
if((Rt = fork()) == 0){ // child process
pthread_mutex_lock(&Mutex1);
//critical section
pthread_mutex_unlock(&Mutex1);
}
else{ // parent process
pthread_mutex_lock(&Mutex1);
//critical section
pthread_mutex_unlock(&Mutex1);
}
//...
return(0);
}
本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。
同步任务之间的关系开始-开始关系(SS) 虚拟人(avatar)的嘴巴和声音同时执行
结束-开始关系(FS) 任务A不能结束直至任务B开始运行类似于父子进程,父进程产生一个子进程或者父进程从子进程接收到子进程已经开始运行的通信之前,父进程不能完全执行某些操作。
开始-结束关系(SF) 一个任务不能开始,直至另一个任务结束,在管道中读取数据
结束-结束关系(FF) 任务B结束之前,任务A不能结束。父进程必须等待子进程终止之后才能终止
同步数据的访问进程间共享数据的一种方法就是创建一个存储器块,然后将这个存储器块映射到需要共享该数据的进程的地址空间中;另一种方法就是在两个进程的地址空间外创建一个存储器块。IPC(Inter Process Communication)包括:管道、文件、和消息传递。在一个多线程环境中,必须对共享存储器、全局变量和文件的并发访问进行同步。临界区(Critical Section)是可以改变文件指针位置、写文件、关闭文件和读写全局变量或数据结构的任何代码块。
信号量信号量(semaphore)是管理同步关系和实现访问策略的一种同步机制。仅能被某些特定的操作访问。作为资源访问的关键字,这个关键字在某一时刻只能由一个进程或线程拥有。不管那个任务拥有该关键字,那么这个任务就对资源加锁,并独自使用这个资源。
P()是减少操作lock,V()增加操作unlock
P(Mutex)
if(Mutex > 0) {
Mutex--;
}
else {
Block on Mutex;
}
V(Mutex)
if(Blocked on Mutex N processes) {
pass on Mutex;
}
else{
Mutex++;
}
这两个操作的实现依赖于系统。信号量有几类:二进制信号量只有值0或1;计数信号量:一些非负的整数值。POSIX(Portable Operating System UNIX)定义了几种信号量。
1.互斥锁信号量 实现代码临界区互斥机制,通过串行化对临界区的访问来避免竞争的产生。基本操作
pthread_mutex_t Functions Mutex Operations
Function Prototypes/Macros #include <pthread.h>
Initialization
int pthread_mutex_init(pthread_mutex_t *restrict
mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
Request ownership
<time.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_timedlock(pthread_mutex_t
*restrict mutex, const struct tiemspec *restrict
abs_timeout);
Release ownership
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Try ownership
int pthread_mutex_trylock(pthread_mutex_t *mutex);
Destruction
int pthread_mutex_destroy(pthread_mutex_t *mutex);
互斥锁有一个属性对象,传递给初始化函数,创建一个互斥锁,如果采用缺省属性可以使用宏pthread_mutext Mutex = PTHREAD_MUTEX_INITIALIZER;这种方法开销较小,但是不执行任何错误检查。
一个互斥锁可以是专有或共有的。请求所有权操作将互斥锁的所有权授予调用它的进程或线程。一旦互斥锁已经是专有的,那么线程或进程就可以对资源进行访问。如果其他进程或线程试图拥有互斥锁,这些进程或线程就会被阻塞,直到互斥锁可以利用。Try ownership用来测试一个互斥锁是否是专有的(owned),如果互斥锁是专有的,调用这个函数的进程或线程不会被阻塞,如果互斥锁是共有的(unowned),就授予该进程或线程专有权。如果存储器是专有或这有线程在等待这个互斥锁,那么存储器就不能被释放或者关闭(Destruction)。互斥锁实现EREW互斥读和互斥写
互斥锁属性对象的使用方法和线程属性对象的使用方法类似。封装互斥锁对象的所有属性。私有的互斥锁只能在相同的进程中的线程间共享;共享的互斥锁可以由对互斥锁所在存储器位置进行访问的任何线程使用,包括其他进程中的线程。
// ...
pthread_t ThreadA,ThreadB;
pthread_mutex_t Mutex;
pthread_mutexattr_t MutexAttr;
void *task1(void *X)
{
pthread_mutex_lock(&Mutex);
// critical section of code
pthread_mutex_unlock(&Mutex);
return(0);
}
void *task2(void *X)
{
pthread_mutex_lock(&Mutex);
// critical section of code
pthread_mutex_unlock(&Mutex);
return(0);
}
int main(void)
{
//...
pthread_mutexattr_init(&MutexAttr);
pthread_mutex_init(&Mutex,&MutexAttr);
//set mutex attributes
pthread_create(&ThreadA,NULL,task1,NULL);
pthread_create(&ThreadB,NULL,task2,NULL);
//...
return(0);
}
int Rt;
pthread_mutex_t Mutex1;
pthread_mutexattr_t MutexAttr;
int main(void)
{
//...
pthread_mutexattr_init(&MutexAttr);
pthread_mutexattr_setpshared(&MutexAttr,
PTHREAD_PROCESS_SHARED);//初始化为共享
pthread_mutex_init(&Mutex1,&MutexAttr);
if((Rt = fork()) == 0){ // child process
pthread_mutex_lock(&Mutex1);
//critical section
pthread_mutex_unlock(&Mutex1);
}
else{ // parent process
pthread_mutex_lock(&Mutex1);
//critical section
pthread_mutex_unlock(&Mutex1);
}
//...
return(0);
}
本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。
相关文章推荐
- C++ 并行与分布式编程 chapter5 任务间并发的同步(2)
- C++并发编程实战chapter1你好,C++的并发世界--笔记1--任务并行和数据并行
- C++并行与分布式编程chater3 将C++程序分成多个任务
- C# 并行编程 之 Barrier的使用 - 通过屏障同步并发任务
- C# 并行编程 之 Barrier的使用 - 通过屏障同步并发任务
- C# 并行编程 之 Barrier的使用 - 通过屏障同步并发任务
- C++11 并发编程基础(一):并发、并行与C++多线程
- C++11 并发编程基础(一):并发、并行与C++多线程
- Hadoop并行计算原理与分布式并发编程
- GCD编程dispatch_sync(同步)和dispatch_async(异步)方式执行并发队列任务区别
- Hadoop并行计算原理与分布式并发编程
- Java 并发编程实战学习笔记——串行任务转并行任务
- Java 并发编程实战学习笔记——路径查找类型并行任务的终止
- Atitit 三种并发编程模型 艾龙 attilax总结 1. 并发系统可以使用不同的并发模型去实现。 1 2. 并行工作者 并行工作者模型。进来的任务分配给不同的工作者 银行模式 2 2.1.
- Java 并发编程之任务取消(五)
- 并发 并行 同步 异步 阻塞 非阻塞
- Java并发编程 之 同步队列与等待队列
- Java高并发编程——为IO密集型应用设计线程数与划分任务
- 用 Hadoop 进行分布式并行编程, 第 1 部分
- IOS串行队列、并行队列进行同步或者异步任务解析