`
shake863
  • 浏览: 661320 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux下编程学习----- 线程同步之无名信号量

阅读更多

 

这是一个书上的例子,逻辑是:一个线程生产一组数字1、2、3..... 等等,放入一个循环队列中。另一个线程去处理这些数字,达到的效果是把这些数字求和。还是看看代码吧。 


#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <semaphore.h>
#define BUFSIZE 4
#define NUMBER 8

int sum_of_number=0;
/* 可读 和 可写资源数*/
sem_t write_res_number;
sem_t read_res_number;

/* 循环队列 */
struct recycle_buffer{
    int buffer[BUFSIZE];
    int head,tail;
}re_buf;

/* 用于实现临界区的互斥锁,我们对其初始化*/
pthread_mutex_t buffer_mutex=PTHREAD_MUTEX_INITIALIZER;

static void *producer(void * arg)
{
    int i;
    for(i=0;i<=NUMBER;i++)
    {
        /* 减少可写的资源数 */
        sem_wait(&write_res_number);
        /* 进入互斥区 */
        pthread_mutex_lock(&buffer_mutex);
        /*将数据复制到缓冲区的尾部*/
        re_buf.buffer[re_buf.tail]=i;
        re_buf.tail=(re_buf.tail+1)%BUFSIZE;
        printf("procuder %d write %d.\n",pthread_self(),i);
        /*离开互斥区*/
        pthread_mutex_unlock(&buffer_mutex);
        /*增加可读资源数*/
        sem_post(&read_res_number);
    }
   
    /* 线程终止,如果有线程等待它们结束,则把NULL作为等待其结果的返回值*/
    return NULL;
}

static void * consumer(void * arg)
{
    int i,num;
   
    for(i=0;i<=NUMBER;i++)
    {
        /* 减少可读资源数 */
        sem_wait(&read_res_number);
        /* 进入互斥区*/
        pthread_mutex_lock(&buffer_mutex);
        /* 从缓冲区的头部获取数据*/
        num = re_buf.buffer[re_buf.head];
        re_buf.head = (re_buf.head+1)%BUFSIZE;
        printf("consumer %d read %d.\n",pthread_self(),num);
        /* 离开互斥区*/
        pthread_mutex_unlock(&buffer_mutex);
        sum_of_number+=num;
        /* 增加客写资源数*/
        sem_post(&write_res_number);
    }       
    /* 线程终止,如果有线程等待它们结束,则把NULL作为等待其结果的返回值*/
    return NULL;
}

int main(int argc,char ** argv)
{
    /* 用于保存线程的线程号 */
    pthread_t p_tid;
    pthread_t c_tid;
    int i;
   
    re_buf.head=0;
    re_buf.tail=0;
    for(i=0;i<BUFSIZE;i++)
        re_buf.buffer[i] =0;
   
    /* 初始化可写资源数为循环队列的单元数 */
    sem_init(&write_res_number,0,BUFSIZE);    //  这里限定了可写的bufsize,当写线程写满buf时,会阻塞,等待读线程读取
    /* 初始化可读资源数为0 */
    sem_init(&read_res_number,0,0);
   
    /* 创建两个线程,线程函数分别是 producer 和 consumer */
    /* 这两个线程将使用系统的缺省的线程设置,如线程的堆栈大小、线程调度策略和相应的优先级等等*/
    pthread_create(&p_tid,NULL,producer,NULL);
    pthread_create(&c_tid,NULL,consumer,NULL);
   
    /*等待两个线程完成退出*/
    pthread_join(p_tid,NULL);
    pthread_join(c_tid,NULL);
    printf("The sun of number is %d\n",sum_of_number);
}

 

编译命令:gcc -g -o threadtest threadtest.c -lpthread

分享到:
评论

相关推荐

    Linux下C语言编程--进程通信、消息管理

    本文将详细介绍Linux环境下C语言编程中的几种进程通信方法,包括POSIX无名信号量、System V信号量、System V消息队列以及System V共享内存。 #### 1. POSIX无名信号量 ##### 理论基础 信号量是一种用于控制多个...

    无名信号量示例代码

    在Linux系统编程中,线程同步与互斥是多线程程序设计中至关重要的概念,它们确保了共享资源的安全访问,防止数据竞争和死锁等问题。无名信号量是一种常用的同步机制,它允许线程之间通过计数值进行通信,以控制对...

    深入浅出Linux环境编程(进程基础+IPC+POSIX+线程同步与互斥)配套资料

    - POSIX匿名信号量和系统V IPC的信号量都是用于控制资源访问的计数器,实现线程同步。 - 线程取消和线程死锁是线程编程中需要考虑的问题,例如`pthread_cancel()`用于取消线程,死锁则需通过避免循环等待条件来...

    Linux系统编程-(pthread)线程创建与使用.zip

    进程间通信(IPC)方式包括共享内存、消息队列、信号量、有名管道、无名管道、信号和socket等,这些通信方式通常涉及到上下文切换,速度相对较慢。 - **线程**:是进程内的执行单元,共享进程资源,如内存空间。每...

    linux的进程线程编程(高清书签版)

    共享内存是一种效率较高的IPC方式,允许多个进程共享同一段内存空间,但是需要使用信号量来实现同步和互斥。消息队列则是基于消息的发送和接收来进行进程间的通信。 Linux系统信号处理也是进程编程中的一大重点。...

    linux进程链、进程扇和信号量实现生产者--消费者模型实验报告

    通过对生产者-消费者模型的实现,学生将学习如何在Linux环境下运用无名信号量来保护临界资源,同时提升对文件I/O操作的掌握。 二、实验内容 实验分为三个部分: 1. 使用链式结构创建10个子进程,形成进程链。 2. ...

    很全面的资料:Linux之信号量

    信号量是操作系统中用于多任务环境下资源管理的一种机制,尤其在Linux系统中,信号量在进程和线程同步中扮演着关键角色。它们主要用于保护共享资源,确保在某一时刻只有一个进程或线程能够访问特定的资源,避免因...

    linux 进程线程小程序

    在Linux操作系统中,进程和线程是两个核心概念,它们是程序...通过学习这个教程,你将能够熟练掌握Linux环境下的进程与线程管理,以及如何利用信号量、管道和共享内存实现进程间有效通信,为系统级编程打下坚实的基础。

    linux下C语言编程(进程通信、消息队列)

    无名信号量是POSIX标准中定义的同步机制,它允许操作系统的进程和线程对共享资源进行互斥访问和同步。无名信号量不通过文件描述符进行访问,而是在进程的地址空间内操作,因此只能在创建它们的进程中使用,无法跨...

    linux系统编程试卷(答案).docx

    - 互斥确保同一时间只有一个线程访问资源,而同步则控制线程的执行顺序,通常使用互斥锁和信号量等机制实现。 10. **特殊进程类型**: - 僵尸进程是已退出但其父进程未收集其退出状态的进程。孤儿进程是父进程...

    linux串口、多线程、进程、网络

    在Linux中,线程由pthread库提供,`pthread_create()`用于创建新线程,`pthread_join()`等待线程结束,`pthread_mutex_*`系列函数用于互斥锁实现线程同步,防止竞态条件。线程局部存储(TLS, Thread Local Storage)...

    LINUX 高级编程

    9. **进程间通信(IPC)**:Linux提供了多种进程间通信方式,如管道(无名管道和命名管道)、消息队列、共享内存、信号量等,这些都用于不同进程之间的数据交换和协调。 10. **系统调用接口(System Call Interface...

    linux网络编程全套代码

    无名信号量(内存信号量): sem_t, p, v, 互斥锁:pthread_mutex_t 进程: Fork()/ execve();// system(); 进程内存空间 环境变量: 从哪里来, 放在那里, 如何取用 进程通信: 传统: 无名管道 pipe: 亲缘...

    Linux下多线程编程的互斥与同步

    在Linux中,实现了POSIX无名信号量,这些信号量可以在线程间共享。以下是一些重要的函数: 1. `sem_init`:用于创建信号量,并设定其初始值。第二个参数`pshared`在当前的Linux实现中必须为0,意味着信号量仅限于...

Global site tag (gtag.js) - Google Analytics