▶ 使用信号量来进行线程间信息传递

● 代码

 #include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#pragma comment(lib, "pthreadVC2.lib") const int thread = , messageSize = ;
char messageList[thread][messageSize]; // 全局信息列表
sem_t sem[thread]; // 各线程信号量,注意每个线程都有一个 void* sendMessage(void* rank)
{
const long long localRank = (long long)rank, dest = (localRank + ) % thread;
int i;
sprintf_s(messageList[dest], messageSize, "Hello from %2d to %2d.", localRank, dest);
sem_post(&sem[dest]); // 解锁 dest 的信号量,因为上一行低吗已经完成了写入,注意每次执行完函数 sem_post() 后 sem[dest] 的值增加 1
sem_wait(&sem[localRank]); // 等待自己编号的信号量解锁,注意每次执行完函数 sem_wait() 后 sem[localRank] 的值减小 1(但不会小于0)
printf("Thread %2d > %s\n", localRank, messageList[localRank]);
return nullptr;
} int main()
{
pthread_t pth[thread];
int i;
long long list[thread]; for (i = ; i < thread; i++)
{
sem_init(&sem[i], , ); // 依次初始化信号量
list[i] = i;
pthread_create(&pth[i], nullptr, sendMessage, (void *)list[i]);
}
for (i = ; i < thread; i++)
{
pthread_join(pth[i], nullptr);
sem_destroy(&sem[i]); // 销毁信号量
}
printf("\nfinish.\n");
getchar();
return ;
}

● 输出结果

 Thread   > Hello from   to  .
Thread > Hello from to .
Thread > Hello from to .
Thread > Hello from to .
Thread > Hello from to .
Thread > Hello from to .
Thread > Hello from to .
Thread > Hello from to . finish.

● 用到的定义,注意信号量不是由 phread.h 提供的,而是 semaphore.h

 typedef struct sem_t_ * sem_t;

 PTW32_DLLPORT int __cdecl sem_init(sem_t * sem, int pshared, unsigned int value);
// 初始化信号量,输入一个已经声明的信号量的指针,第二个参数不明,第三个参数为 0 表示初始化完成后信号量为上锁状态 PTW32_DLLPORT int __cdecl sem_destroy(sem_t * sem);// 销毁信号量 PTW32_DLLPORT int __cdecl sem_wait(sem_t * sem); // 等待信号量为解锁状态再向下运行 PTW32_DLLPORT int __cdecl sem_post(sem_t * sem); // 解锁信号量

▶ 使用忙等待和互斥量来实现路障

● 代码

 #include <stdio.h>
#include <pthread.h>
#pragma comment(lib, "pthreadVC2.lib") const int thread = ;
int count;
pthread_mutex_t pmt; void* work(void* rank)
{
const long long localRank = (long long)rank, dest = (localRank + ) % thread;
pthread_mutex_lock(&pmt); // 进入读写区,上锁,计数器加一,解锁
printf("Thread %2d reached the barrier.\n", localRank); fflush(stdout);
count++;
pthread_mutex_unlock(&pmt);
while (count < thread); // 使用忙等待来等所有的线程都达到栅栏
printf("Thread %2d passed the barrier.\n", localRank); fflush(stdout);
return nullptr;
} int main()
{
pthread_t pth[thread];
int i;
long long list[thread];
pthread_mutex_init(&pmt, nullptr);
for (i = count = ; i < thread; i++)
{
list[i] = i;
pthread_create(&pth[i], nullptr, work, (void *)list[i]);
}
for (i = ; i < thread; i++)
pthread_join(pth[i], nullptr);
pthread_mutex_destroy(&pmt);
printf("\nfinish.\n");
getchar();
return ;
}

● 输出结果

 Thread   reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier. finish.

▶ 使用信号量来实现路障

● 代码

 #include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#pragma comment(lib, "pthreadVC2.lib") const int thread = ;
int count;
sem_t sem_count, sem_barrier; void* work(void* rank)
{
const long long localRank = (long long)rank, dest = (localRank + ) % thread;
printf("Thread %2d reached the barrier.\n", localRank); fflush(stdout);
sem_wait(&sem_count); // 等待允许访问计数器 count,注意执行完该语句时 sem_count 值减 1,自动上锁
if (count == thread - ) // 最后一个到达进入的线程
{
count = ; // 计数器清零,以后可以重复使用
sem_post(&sem_count); // 计数器解锁,sem_count 值加 1
for (int i = ; i < thread - ; sem_post(&sem_barrier), i++);// 解锁整个栅栏,
} // 每有一个线程通过后面的语句 sem_wait(&sem_barrier);,
else // 前面到达的线程 // sem_barrier 的值就减 1,所以这里要为该变量加上 thread - 1
{
count++; // 计数器加一
sem_post(&sem_count); // 解锁计数器
sem_wait(&sem_barrier); // 等待栅栏解锁
}
printf("Thread %2d passed the barrier.\n", localRank); fflush(stdout);
return nullptr;
} int main()
{
pthread_t pth[thread];
int i;
long long list[thread]; sem_init(&sem_count, , ); // 计数器锁初始化为 1,开锁状态
sem_init(&sem_barrier, , ); // 栅栏初始化为 0,关锁状态
for (i = count = ; i < thread; i++)
{
list[i] = i;
pthread_create(&pth[i], nullptr, work, (void *)list[i]);
}
for (i = ; i < thread; i++)
pthread_join(pth[i], nullptr);
sem_destroy(&sem_count), sem_destroy(&sem_barrier);
printf("\nfinish.\n");
getchar();
return ;
}

● 输出结果

Thread   reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier. finish.

▶ 使用条件变量来实现路障

 #include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#pragma comment(lib, "pthreadVC2.lib") const int thread = ;
int count;
pthread_mutex_t mutex;
pthread_cond_t cond; void* work(void* rank)
{
const long long localRank = (long long)rank, dest = (localRank + ) % thread;
printf("Thread %2d reached the barrier.\n", localRank); fflush(stdout);
pthread_mutex_lock(&mutex); // 上锁
count++;
if (count == thread) // 最后一个进入的线程
{
count = ; // 计数器清零
pthread_cond_broadcast(&cond); // 广播所有线程继续向下执行
}
else
for (; pthread_cond_wait(&cond, &mutex) != ;);// 等待其他线程
pthread_mutex_unlock(&mutex); // 条件变量阻塞解除后会自动将互斥量上锁,需要手工解除 printf("Thread %2d passed the barrier.\n", localRank); fflush(stdout);
return nullptr;
} int main()
{
pthread_t pth[thread];
int i;
long long list[thread];
pthread_mutex_init(&mutex, nullptr);
pthread_cond_init(&cond, nullptr);
for (i = count = ; i < thread; i++)
{
list[i] = i;
pthread_create(&pth[i], nullptr, work, (void *)list[i]);
}
for (i = ; i < thread; i++)
pthread_join(pth[i], nullptr);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
printf("\nfinish.\n");
getchar();
return ;
}

● 输出结果

Thread   reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread reached the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier.
Thread passed the barrier. finish.

● 用到的定义,pthread.h

 typedef struct pthread_cond_t_ * pthread_cond_t;

 PTW32_DLLPORT int PTW32_CDECL pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * attr);// 初始化已经声明了的条件变量,第二个参数为属性指针

 PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy(pthread_cond_t * cond);                              // 销毁条件变量

 PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex);        // 阻塞线程以等待 signal 或 brocast

 PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal(pthread_cond_t * cond);                               // 解锁一个线程

 PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast(pthread_cond_t * cond);                            // 解锁所有的线程

Pthreads 信号量,路障,条件变量的更多相关文章

  1. 学习pthreads,使用条件变量进行多线程之间的同步

    条件变量提供另一种多线程同步的方法.互斥量通过控制对共享数据的访问来同步任务.条件变量可以根据数据的值来同步任务.条件变量是当一个事件发生时发送信号的信号量.一旦事件发生,可能会有多个线程在等待信号, ...

  2. 27 python 初学(信号量、条件变量、同步条件、队列)

    参考博客: www.cnblogs.com/yuanchenqi/articles/5733873.html  semaphore 信号量: condition 条件变量: event 同步条件:条件 ...

  3. Python:Day29 信号量、条件变量

    信号量:semaphore 信号量是用来控制线程并发数的.(理解:虽然GIL任意时刻都只有一个线程被执行,但是所有线程都有资格去抢,semaphore就是用来控制抢的GIL的数量,只有获取了semap ...

  4. QThread中的互斥、读写锁、信号量、条件变量

    该文出自:http://www.civilnet.cn/bbs/browse.php?topicno=78431 在gemfield的<从pthread到QThread>一文中我们了解了线 ...

  5. 【Qt开发】QThread中的互斥、读写锁、信号量、条件变量

    在gemfield的<从pthread到QThread>一文中我们了解了线程的基本使用,但是有一大部分的内容当时说要放到这片文章里讨论,那就是线程的同步问题.关于这个问题,gemfield ...

  6. 第二章 信号量及条件变量(三)——> 重点

    2.4.4 信号量的应用 1. 利用信号量实现进程互斥   为使多个进程能互斥的访问某临界资源,只需为该资源设置一个互斥信号量mutex,并设置其初值为 1 ,然后讲个进程访问该资源的临界区CS置于w ...

  7. 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)

    注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...

  8. linux条件变量使用和与信号量的区别

    近来在项目中用到条件变量和信号量做同步时,这一块一直都有了解,但也一直没有总结,这次总结一下,给大家提供点参考,也给自己留点纪念. 首先,关于信号量和条件变量的概念可以自行查看APUE,我这直接把AP ...

  9. pThreads线程(三) 线程同步--条件变量

    条件变量(Condition Variables) 参考资料:http://game-lab.org/posts/posix-thread-cn/#5.1 条件变量是什么? 条件变量为我们提供了另一种 ...

随机推荐

  1. Numpy np.array 相关常用操作

    https://www.cnblogs.com/oftenlin/p/7856389.html

  2. git-it 教程,一些git知识点。/ 如何解决merge conflict/ 如何使用Github Pages./Git术语表

    一个git使用教程 https://:.com/jlord/git-it-electron#what-to-install 一个在线Github的功能教学:https://lab.github.com ...

  3. bzoj 1318 [SPOJ744] Longest Permutation (排列)

    大意: 给定序列, 求选出一个长度为k的区间, 使得区间内的数为[1,k]的排列, 且要求k最大 这题好神啊. 每个排列有且仅有一个1, 我们按1将序列分成若干子问题来处理, 而每个位置最多属于两个子 ...

  4. UVA-1660 Cable TV Network (最小割)

    题目大意:给一张n个点.m条边的无向图,求最小点割集的基数. 题目分析:求无向图最小点割集的基数可以变成求最小割.考虑单源s单汇t的无向图,如果要求一个最小点集,使得去掉这个点集后图不再连通(连通分量 ...

  5. 理解 Ruby Symbol (Ruby中的冒号)

    http://blog.csdn.net/besfanfei/article/details/7966850 一直不明白:的作用 直到看到这篇文章 豁然开朗 处理符号相比字符串,占用更少的资源

  6. FZU 2169 shadow spfa

    题目链接:shadow 好佩服自己耶~~~好厉害~~~ 麻麻再也不用担心我的spfa 和 邻接表技能了~~~ spfa 记录最短路径. #include <stdio.h> #includ ...

  7. python自动化运维之路2

    list列表 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 #!/usr/bin/env python # _*_ encoding:utf-8 _*_ # a ...

  8. bzoj1067

    题意: 给你下雨量,让你判断每一句话是否正确 题解: 线段树 用来维护判断 代码: #include <cstdio> #include <cstring> #include ...

  9. FOR UPDATE

    1. for update的使用场景 `如果遇到存在高并发并且对于数据的准确性很有要求的场景,是需要了解和使用for update的.    比如涉及到金钱.库存等.一般这些操作都是很长一串并且是开启 ...

  10. C++17中那些值得关注的特性(上)

    C++17标准在2017上半年已经讨论确定,正在形成ISO标准文档,今年晚些时候会正式发布.本文将介绍最新标准中值得开发者关注的新特新和基本用法. 总的来说C++17相比C++11的新特性来说新特性不 ...