首页 > 其他分享 >利用信号量实现线程顺序执行

利用信号量实现线程顺序执行

时间:2024-06-14 20:44:25浏览次数:10  
标签:顺序 Thread 信号量 finished 线程 sem NULL

线程顺序循环执行的场景在多线程编程中并不罕见,尤其是在需要协调多个线程按特定顺序重复执行任务的情况下。以下是几个常见的例子:

  1. 生产者-消费者模型:在这种模型中,生产者线程生成数据并将其放入缓冲区,而消费者线程从缓冲区取出数据进行处理。这种情况下,生产者和消费者线程通常按顺序交替运行。
  2. 流水线处理:在某些应用中,数据处理分为多个步骤,每个步骤由不同的线程负责。例如,在图像处理流水线中,可能有一个线程读取图像数据,一个线程处理图像,一个线程保存处理后的图像。每个线程按顺序操作,形成一个循环处理流水线。
  3. 周期性任务调度:某些系统需要周期性地执行一组任务,例如传感器数据采集系统,每个传感器的数据采集线程需要按顺序运行,并且在一定时间后重新开始。

为了更好地理解,我们可以通过一个具体的例子来说明如何使用信号量和多线程实现顺序循环执行。

利用POSIX无名信号量实现三个线程 T1、T2 和 T3,按顺序循环执行各自的任务。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define NUM_ITERATIONS 3

sem_t sem1, sem2, sem3;

void* thread1(void* arg) {
    for (int i = 0; i < NUM_ITERATIONS; ++i) {
        sem_wait(&sem1);  // 等待信号量
        printf("Thread 1 is running\n");
        sleep(1);  // 模拟工作
        printf("Thread 1 has finished\n");
        sem_post(&sem2);  // 通知thread2可以开始
    }
    return NULL;
}

void* thread2(void* arg) {
    for (int i = 0; i < NUM_ITERATIONS; ++i) {
        sem_wait(&sem2);  // 等待信号量
        printf("Thread 2 is running\n");
        sleep(1);  // 模拟工作
        printf("Thread 2 has finished\n");
        sem_post(&sem3);  // 通知thread3可以开始
    }
    return NULL;
}

void* thread3(void* arg) {
    for (int i = 0; i < NUM_ITERATIONS; ++i) {
        sem_wait(&sem3);  // 等待信号量
        printf("Thread 3 is running\n");
        sleep(1);  // 模拟工作
        printf("Thread 3 has finished\n");
        sem_post(&sem1);  // 通知thread1可以开始
    }
    return NULL;
}

int main() {
    pthread_t t1, t2, t3;

    // 初始化信号量
    sem_init(&sem1, 0, 1);  // 初始信号量为1,使线程1首先运行
    sem_init(&sem2, 0, 0);
    sem_init(&sem3, 0, 0);
/*
 int sem_init(sem_t *sem, int pshared, unsigned int value);
 pshared信号量的作用范围,0为线程间,非0为进程间
 value 信号量值,首先执行的线程信号量设置为1,其他的为0
*/
    // 创建线程
    pthread_create(&t1, NULL, thread1, NULL);
    pthread_create(&t2, NULL, thread2, NULL);
    pthread_create(&t3, NULL, thread3, NULL);

    // 等待所有线程完成
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_join(t3, NULL);

    // 销毁信号量
    sem_destroy(&sem1);
    sem_destroy(&sem2);
    sem_destroy(&sem3);

    printf("All threads have finished execution.\n");

    return 0;
}

输出结果:

Thread 1 is running
Thread 1 has finished
Thread 2 is running
Thread 2 has finished
Thread 3 is running
Thread 3 has finished
Thread 1 is running
Thread 1 has finished
Thread 2 is running
Thread 2 has finished
Thread 3 is running
Thread 3 has finished
Thread 1 is running
Thread 1 has finished
Thread 2 is running
...

标签:顺序,Thread,信号量,finished,线程,sem,NULL
From: https://www.cnblogs.com/cino/p/18248606

相关文章

  • java多线程学习笔记——“并发提高效率”
    java的内存分配与管理如果要学习多线程,我们必须先对java的内存分配和管理有一定的了解java的分区包括:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、运行时常量池这几个部分。栈区栈区有以下几个特点:1、线程私有,每个线程都会拥有自己的栈2、每个方法在被调用......
  • 数据结构:手撕代码——顺序表
     目录 1.线性表2.顺序表2.1顺序表的概念2.2动态顺序表实现 2.2-1动态顺序表实现思路2.2-2动态顺序表的初始化 2.2-3动态顺序表的插入检查空间 尾插头插 中间插入 2.2-4 动态顺序表的删除 尾删头删 中间删除 2.2.5动态顺序表查找与打印、销毁......
  • 探索Spring虚拟线程:高效并发编程的新选择
    目录什么是虚拟线程虚拟线程的优势Java虚拟线程的历史背景在Spring中使用虚拟线程配置Spring支持虚拟线程使用虚拟线程执行任务虚拟线程与传统线程池的对比实战案例:构建高并发Web应用案例描述项目设置代码实现性能测试与结果分析最佳实践与注意事项结论参考资料什么是......
  • 数据结构(C/C++)专题一:顺序表与链表
    今天开始一个新的专题:数据结构当然,不仅仅适用于学习也适用于408考研。那么提起数据结构思维导图:总结如下:·1.初识顺序表与链表首先呢我们要明白,数据结构有物理结构,也有逻辑结构物理结构就是电脑实际的结构,链式,非链式,索引,散列eg:链式结构(LinkedStructure)例子:火车车......
  • 设置springboot scheduled多线程,解决多个定时任务并发问题(转载)
    项目上有几个定时任务都是同时间点要执行的,最近发现多个定时任务为单线程排队执行,后来经过查资料发现@schedule注解默认是单线程的,如果定时任务比较多或者有的定时任务比较耗时,会影响到其他定时任务的执行,通过以下方法解决多个定时任务同时并发执行问题。第1种:增加配置类@Configu......
  • Redis之线程IO模型
    引言Redis是个单线程程序!这点必须铭记。除了Redis之外,Node.js也是单线程,Nginx也是单线程,但是他们都是服务器高性能的典范。Redis单线程为什么能够这么快!因为他所有的数据都在内存中,所有的运算都是内存级别的运算。正因为Redis是单线程,所以要小心使用Redis指令,对于那些时......
  • 线程、进程、并发和并行的概念
    线程、进程、并发和并行的概念进程:是指一个在内存中正在运行的程序,是操作系统分配资源(文件、io、网络、内存等资源)的基本单位。一个程序文件(也就是我们编写、编译好的程序,是保存在磁盘中的,例如.exe程文件),当我们点击,程序文件就被加载到内存中,也就创建了一个进程。同一个程......
  • 文件IO,创建编号为ABC三个线程,三个线程循环打印自己的编号,要求打印出来的结果必须是ABC
    第二个,拷贝图片#include<myhead.h>typedefstruct{ constchar*srcfile; constchar*destfile; intlen;}info;void*task1(void*arg){ infobuf=*((info*)(arg)); //打开这两个文件,只读的形式 intfd=-1; if((fd=open(buf.srcfile,O_RDONLY))==-1) {......
  • 多线程与多进程
    1.进程和线程的定义进程线程的定义:进程可以理解为在操作系统中一个运行起来的程序(程序是指令、数据及其组织形式,进程是程序的实体),是操作系统进行资源分配的最小单位。线程是进程中的一个执行流,是操作系统进行系统调度的最小单位,一个进程由一个或多个线程组成。2.多进程和多线程......
  • 爬虫 | 多线程、多进程、协程
    进程和线程"""进程中至少有一条线程,线程和进程的开启非常类似,这里就展示线程"""fromthreadingimportThreadfrommultiprocessingimportProcess#第一种开启的方法就是直接defdeffunc(name):foriinrange(100):print(name,i)if__name__=='__ma......