Semaphore (realize thread synchronization and mutual exclusion)

Semaphore:

Function: realize synchronization and mutual exclusion between threads
 Essence: a counter (do resource count - judge whether the current critical resource can be operated) + wait + wake up + wait queue
    Principle:
        Mutex principle: mutex can be realized when there is only 0 or 1 count. The initial count is 1. 1 means that only one thread can obtain resources at present;
                 After obtaining resources - 1, + 1 after the operation is completed, when the count is 0, other threads wait (add PCB to the waiting queue)  
        Synchronization principle: control the program logic (control the reasonable operation of critical resources); judge whether the current critical resources can be controlled by counting
                 If the source is accessed and cannot be operated (count < = 0), wait;

Related interfaces

Defining semaphore variables

Variable type: SEM? Header file:? Include < semaphore. H > 

Initialization semaphore

 int sem_init(sem_t *sem, int pshared, unsigned int value);
 sem: Defined signal variables
 pshared: 0 Represents a signal in a thread, Nonzero indicates the semaphore between processes
 value:  Initial value of semaphore

Destroy semaphore

 int sem_destroy(sem_t* sem);

Waiting semaphore

 Function: wait for the semaphore, and the semaphore value will be reduced by 1
 int sem_wait(sem_t *sem); 

Issued semaphore

 Function: issue semaphore to indicate that the resource has been used and can be returned. Add the semaphore value to 1. 
 int sem_post(sem_t *sem); 

Realization of producer consumer model by semaphore

Process: the producer thread adds data to the warehouse (a circular queue), in which the consumer thread fetches the data

Encapsulation model class

The specific code is as follows:

#include <iostream>
#include <semaphore.h>
#include <pthread.h>
#include <vector>
#include <stdio.h>
using namespace std;
#define MAX_SOTR 5

class Sem_PC_test{
  private:
    sem_t _lock;  // Mutual exclusion for storage warehouse
    sem_t _data; // Count of thread warehouse capacity for consumers
    sem_t _prod; // Count for the capacity of the producer thread warehouse
    vector<int> _stor; // Define a warehouse
    int _wirte; // The write location is used to implement a circular queue
    int _read; // The read location is used to implement the circular queue

  public:
    Sem_PC_test(const int cap = MAX_SOTR) 
      :_stor(cap)
      ,_wirte(0)
      ,_read(0)
    {
      sem_init(&_lock, 0, 1);   // Initialization lock
      sem_init(&_data, 0, 0);
      sem_init(&_prod, 0, MAX_SOTR);
    }

    ~Sem_PC_test()
    {
      sem_init(&_lock, 0, 1); 
      sem_init(&_data, 0, 0);
      sem_init(&_prod, 0, MAX_SOTR);
    }

    bool Push_data(const int& data)
    {
    sem_wait(&_prod); // Producer thread gets signal value
    sem_wait(&_lock); // Lock up
    _stor[_wirte] = data; 	//Write data
    _wirte = (_wirte+1)% MAX_SOTR; // Implementation of circular queue
    sem_post(&_lock); // Signal (unlock)
    sem_post(&_data);// Signal the conditional variable of the consumer thread
    return true;
    }

    bool Get_data(int& data)
    {
      sem_wait(&_data);
      sem_wait(&_lock);
      data = _stor[_read];
      _read = (_read+1)% MAX_SOTR;
      sem_post(&_lock);
      sem_post(&_prod); 
      return true;
    }
};
void* test_get(void* agr)
{
  int a;
  while(1)
  {
  Sem_PC_test* p = (Sem_PC_test*)agr;
  p->Get_data(a);
  printf("thread%lu,Get the value%d\n", pthread_self(), a);
  }
  return NULL;
}


void* test_push(void* agr)
{
  static int i = 0;
  while(1)
  {
  Sem_PC_test* p = (Sem_PC_test*)agr;
  p->Push_data(i);
  i++;
  }
  return NULL;
}
int main()
{
  pthread_t tid[4], PC[4];
  int i;
  Sem_PC_test data;
  
  for(i=0; i<4; i++)
  {
    pthread_create(&tid[i], NULL ,test_get , (void*)&data);
  }
  for(i=0; i<4; i++)
  {
    pthread_create(&PC[i], NULL , test_push, (void*)&data);
  }
  
  
  for(i=0; i<4; i++)
  {
    pthread_join(tid[i],NULL);
  }

  for(i=0; i<4; i++)
  {
    pthread_join(PC[i],NULL);
  }
  return 0;
}

 Compiled code: G + + SEM UU PC UU test.cpp - O SEM UU PC UU test - lpthread

The operation results are as follows:

Published 45 original articles, won praise 6, visited 4387
Private letter follow

Posted on Sat, 01 Feb 2020 00:02:09 -0800 by Leveecius