首页 > 其他分享 >线程的同步与互斥

线程的同步与互斥

时间:2022-11-14 20:36:05浏览次数:41  
标签:node 同步 int 互斥 phead 线程 pthread mutex NULL

生产者消费者问题

编译指令

gcc -o pc pc.c -lpthread
#include "csapp.h"

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<time.h>

pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //条件变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//互斥量

typedef struct node//链表结点
{
    int data;
    struct node* next;
}node, *node_p, **node_pp;

node_p getnode(int data)//创建结点
{
    node_p ret = malloc(sizeof(node));
    if(ret != NULL)
    {
        ret->data = data;
        ret->next = NULL;
        return ret;
    }
    return NULL;
}

void initlist(node_pp pphead)//初始化链表——创建头结点
{
    if(pphead == NULL)
        exit(1);
    *pphead = malloc(sizeof(node));
    (*pphead)->next = NULL;
}

int isEmpty(node_p phead)//链表判空,空返回1
{
    return (phead->next == NULL)?1:0;
}

void push(node_p phead, int data)//链表的头插
{
    node_p tmp = getnode(data);
    if(tmp != NULL)
    {
        tmp->next = phead->next;
        phead->next = tmp;
    }
}

void print(node_p phead)//打印链表结点的数据
{
    phead = phead->next;
    while(phead)
    {
        printf("%d  ", phead->data);
        phead = phead->next;
    }
}

void erase(node_p phead, int *x)//删除链表的数据
{

    if(isEmpty(phead))
        return;
    node_p cur = phead->next;
    phead->next = cur->next;
    *x = cur->data;
    free(cur);
}

void destroy(node_p phead)//销毁链表
{
    while(!isEmpty(phead))
    {
        int data;
        erase(phead, &data);
    }
    free(phead);
}

void *producer(void* arg)//生产者线程执行的函数
{
    node_p phead = (node_p)arg;
    while(1)
    {
        int data = rand()%1000;
        pthread_mutex_lock(&mutex);
        push(phead, data);
        printf("producer done, %d\n", data);
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond);
        sleep(1);
    }
}

void* consumer(void* arg)//消费者线程执行的函数
{
    node_p phead = (node_p)arg;
    int data = 0;
    while(1)
    {
        pthread_mutex_lock(&mutex);
        while(isEmpty(phead))
        {
            printf("no product, please wait...\n");
            pthread_cond_wait(&cond, &mutex);
        }
        erase(phead, &data);
        printf("consumer done, %d\n", data);
        pthread_mutex_unlock(&mutex);
        usleep(100000);
    }
}
int main()
{
    node_p phead;
    initlist(&phead);

    srand((unsigned long)time(NULL));
    pthread_t t1, t2;
    pthread_create(&t1, NULL, producer, (void*)phead);//生产者线程
    pthread_create(&t2, NULL, consumer, (void*)phead);//消费者线程

    pthread_join(t1, NULL);//线程等待
    pthread_join(t2, NULL);

    destroy(phead);//释放链表
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

读者写者问题

输入数据:

1 R 3 5
2 W 4 5
3 R 5 2
4 R 6 5
5 W 7 3

编译指令

gcc -o wr wr.c -lpthread

运行指令

./wr < data > out

大概需要运行20s。

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

typedef struct {
  int tid;
  int delay;
  int last;
} Role;

enum {
  s_waiting,
  s_reading,
  s_writing
} state = s_waiting;

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t Sig_read;
sem_t Sig_wrt;
int reader_count = 0;
int writer_count = 0;

time_t startTime;

// 读者进程
void* reader(void* argPtr) {
  Role role = *(Role*)argPtr;
  sleep(role.delay);
  printf("[%02.0lf秒]读者进程%d等待读取\n", 
    difftime(time(NULL), startTime), role.tid
  );

  pthread_mutex_lock(&mutex);
    ++reader_count;
    if(state == s_waiting 
    || (state == s_reading && writer_count == 0)) {
      sem_post(&Sig_read);
      state = s_reading;
    }
  pthread_mutex_unlock(&mutex);
  sem_wait(&Sig_read);

  printf("[%02.0lf秒]读者进程%d开始读取\n", 
    difftime(time(NULL), startTime), role.tid
  );

  // read
  sleep(role.last);

  pthread_mutex_lock(&mutex);
    --reader_count;
    if(writer_count != 0) {
      // 有读者在等待
      sem_post(&Sig_wrt);
      state = s_writing;
    } else if(reader_count == 0) {
      // 等待队列为空
      state = s_waiting;
    }
  pthread_mutex_unlock(&mutex);

  printf("[%02.0lf秒]读者进程%d读取结束\n", 
    difftime(time(NULL), startTime), role.tid
  );
  return NULL;
}

// 写者进程
void* writer(void* argPtr) {
  Role role = *(Role*)argPtr;
  sleep(role.delay);
  printf("[%02.0lf秒]写者进程%d等待写入\n", 
    difftime(time(NULL), startTime), role.tid
  );
  pthread_mutex_lock(&mutex);
  ++writer_count;
  if(state == s_waiting) {
    sem_post(&Sig_wrt);
    state = s_writing;
  }
  pthread_mutex_unlock(&mutex);

  sem_wait(&Sig_wrt);
  printf("[%02.0lf秒]写者进程%d开始写入\n", 
    difftime(time(NULL), startTime), role.tid
  );
  // write
  sleep(role.last);

  pthread_mutex_lock(&mutex);
    --writer_count;
    if(writer_count != 0) {
      sem_post(&Sig_wrt);
      state = s_writing;
    } else if(reader_count != 0) {
      for(int i=0; i!=reader_count; ++i) {
        sem_post(&Sig_read);
      }
      state = s_reading;
    } else {
      state = s_waiting;
    }
  pthread_mutex_unlock(&mutex);

  printf("[%02.0lf秒]写者进程%d写入结束\n", 
    difftime(time(NULL), startTime), role.tid
  );
  return NULL;
}

int main() {
  const int MAX_THREAD = 100;
  // 读写进程队列
  pthread_t tid[MAX_THREAD];
  Role role[MAX_THREAD];
  int tidEnd = 0;

  // 初始化信号量
  sem_init(&Sig_read, 0, 0);
  sem_init(&Sig_wrt, 0, 0);

  startTime = time(NULL);

  int arg_tid;
  int arg_delay;
  int arg_last;
  char arg_type;
  while(scanf("%d %c%d%d", &arg_tid, &arg_type, &arg_delay, &arg_last) == 4) {
    assert(tidEnd < MAX_THREAD);
    if(arg_type == 'R') {
      role[tidEnd].tid = arg_tid;
      role[tidEnd].delay = arg_delay;
      role[tidEnd].last = arg_last;
      pthread_create(tid + tidEnd, NULL, reader, role + tidEnd);
    } else {
      role[tidEnd].tid = arg_tid;
      role[tidEnd].delay = arg_delay;
      role[tidEnd].last = arg_last;
      pthread_create(tid + tidEnd, NULL, writer, role + tidEnd);
    }
    printf("[%02.0lf秒]创建进程%d\n", difftime(time(NULL), startTime), arg_tid);
    ++tidEnd;
  }

  for(int i=0; i!=tidEnd; ++i) {
    pthread_join(tid[i], NULL);
  }

  // 销毁信号量
  pthread_mutex_destroy(&mutex);
  sem_destroy(&Sig_read);
  sem_destroy(&Sig_wrt);
}

标签:node,同步,int,互斥,phead,线程,pthread,mutex,NULL
From: https://www.cnblogs.com/coldarra/p/16890307.html

相关文章

  • 线程概念学习笔记
    1.进程和线程1.1什么叫做线程定义:线程是CPU的基本调度单位,每个线程执行的都是进程代码的某个片段。实例演示:用活动监视器的CPU栏目看java进程的线程数的变化左边进......
  • python 多进程 多线程 协程
    多进程-进程池1fromconcurrent.futuresimportProcessPoolExecutor23withProcessPoolExecutor(max_workers=10)asexecutor:4results=executor.map......
  • Pthread 并发编程(二)——自底向上深入理解线程
    Pthread并发编程(二)——自底向上深入理解线程前言在本篇文章当中主要给大家介绍线程最基本的组成元素,以及在pthread当中给我们提供的一些线程的基本机制,因为很多语言的......
  • 《线程调度》
    (38条消息)Linux线程调度与优先级_modi000的博客-CSDN博客_linux线程优先级(38条消息)linux线程调度策略简述_独步逍遥&万界仙踪的博客-CSDN博客_linux线程调度......
  • ActiveMQ经典的使用模式(利用多线程处理消费端)
    今天看视频,里面讲了一个经典的例子,是工作中很常用的,特此将这种模式记录下来.这个例子使用了ActiveMQ的选择器,也使用了之前学的自定义线程池.队列的使用,而且很好的利......
  • 基于AQS实现自定义同步类
    Mutex(互斥锁)Mutex是一个不可重入的互斥锁实现。锁资源(AQS里的state)只有两种状态:0表示未锁定,1表示锁定。下边是Mutex的核心源码:classMuteximplementsLock,java.io.......
  • 响应式编程(反应式编程)的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)
    响应式编程的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)文章目录​​响应式编程的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)​​​​简介​​​​......
  • Java多线程(一)
    一.线程的生命周期及五种基本状态关于Java中线程的生命周期,首先看一下下面这张较为经典的图:   上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知......
  • 线程隔离(舱壁模式)
    线程隔离(舱壁模式)1.线程隔离的实现方式线程隔离有两种方式实现:线程池隔离信号量隔离(Sentinel默认采用)线程池隔离:给每个服务调用业务分配一个线程池,利用线程池本身......
  • Java多线程简介
    一、线程简介Process进程与Thread线程程序是指令和数据的有序集合,本身没有任何运行的含义,为静态概念。进程是执行程序的一次执行过程,为动态概念。是系统资源分配的单位......