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

● 代码

 #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. 爱奇艺vip视频免费看

    代码: <html> <meta charset="utf-8" /> <head> <script> var num = 0; v ...

  2. 查看job的运行日志

    --sys用户执行以下sql语句,查看job的运行日志select t.owner, t.job_name, t.status, to_char(t.actual_start_date, 'yyyy- ...

  3. ossim中Spot5模型bug修复

    ossim中Spot5模型在读取像素视线角时存在一个严重的bug,导致某些点的视线角提取错误. 下面是ossim中getPixelLookAngleX 函数的代码: ossimSpotDimapSup ...

  4. PHP网站自动化配置的实现

    一直都在用yii2做项目,有在用自动化配置,但是没有自己去配置过.中午没事去看了下yii的初始化代码,发现都是php而已! yii2初始化项目代码 所以,我们做项目肯定是可以用php做的,于是我新建了 ...

  5. prototype原型模式

    /** * 原型模式 Prototype * 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象 */ 需求: public class Resume { /** * 要求:一个简历类,必须 ...

  6. 20181009-5 选题 Scrum立会报告+燃尽图 04

    Scrum立会报告+燃尽图(04)选题 此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2194] 一.小组介绍 组长:刘 ...

  7. Alpha冲刺一 (8/10)

    前言 队名:拖鞋旅游队 组长博客:https://www.cnblogs.com/Sulumer/p/10023260.html 作业博客:https://edu.cnblogs.com/campus ...

  8. [leetcode] 204. Count Primes 统计小于非负整数n的素数的个数

    题目大意 https://leetcode.com/problems/count-primes/description/ 204. Count Primes Count the number of p ...

  9. 链表的实现、输出和反向 python

    链表节点包含两个元素:节点的值和指向的下一个节点,因此可以定义链表的类为: class linknode: def __init__(self,value=None,next=None): self. ...

  10. how to play

    陷入难以言说的深深的绝望 无力,无助,暗无天日,看不到光明,看不到未来,不知道何去何从 但我依然坚信这道坎一定可以过去,黎明前的夜总是黑暗的,属于我的光明终将来临 沼泽中的旅行者,只要还没死掉,就还没 ...