POSIX semaphore

  • A semaphore is a critical resource, and its essence is a counter.
  • There are two basic operations of semaphore: P operation and V operation. The P operation is equivalent to decrementing the counter by one, and the V operation is equivalent to adding one to the counter.
  • A semaphore describes the number of critical resources it wants to protect. Because the semaphore itself is also a critical resource, the premise of using it to protect other critical resources is to ensure the atomicity of the operation of the semaphore itself.
  • POSIX semaphores and SystemV semaphores have the same function, and are both used for synchronous operations to achieve conflict-free access to shared resources. Single POSIX can be used for inter-thread synchronization.
  • The operation of the semaphore P is successful, indicating that access to critical resources is allowed.

Common functions for semaphores:

1. Initialize the semaphore

Function prototype: int sem_init(sem_t *sem, int pshared, unsigned int value);

parameter:

pshared: 0 means shared between threads, non-zero means shared between processes.

value: the initial value of the semaphore

2. Destroy the semaphore

Function prototype: int sem_destroy(sem_t *sem);

3. Wait for semaphore

Function prototype: int sem_wait (sem_t *sem);

Function: Waiting for the semaphore, the value of the semaphore will be decremented by one, which is equivalent to performing the P operation on the semaphore.

4. Release semaphore

Function prototype: int sem_post (sem_t *sem);

Function: Release a semaphore, indicating that the resource is used up and the resource can be returned. Adding one to the value of the semaphore is equivalent to performing a V operation on the semaphore.

  • The producer-consumer example is based on a linked list, and its space can be dynamically allocated. Now rewrite this program based on a fixed-size circular queue (POSIX semaphore):

#include<unistd.h>
#include<sys/types.h>
#include<pthread.h>
#include<semaphore.h>
#include<stdio.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>

#define M 6

int ring[M];
sem_t semBlank, semData;

void* runC(void *arg){
    int i = 0;
    int d;
    while(1){
        sem_wait(&semData);
        d = ring[i];
        i++;
        i %= M;
        printf("comsumer done , data is %d\n",d);
        sem_post (& semBlank);
        sleep(1);
    }
}
void* runP(void* arg){
    int d = 0;
    int i = 0;
    while(1){
        sem_wait (& semBlank);
        ring[i] = rand()%123+1;
        d = ring[i];
        i++;
        i %= M;
        printf("product done , data is %d\n",d);
        sem_post(&semData);
    }
}
int main(){
    sem_init (& semBlank, 0, M);
    sem_init(&semData,0,0);

    srand((unsigned long)time(NULL));
    pthread_t t1,t2;
    pthread_create(&t1,NULL,runC,NULL);
    pthread_create(&t2,NULL,runP,NULL);

    pthread_join(t1,NULL);
    pthread_join(t2,NULL);

    sem_destroy(&semBlank);
    sem_destroy(&semData);
}

Result presentation:


通过结果我们可以看出,生产者先生产一些数据,等到生产者生产的数据占满整个环形队列时,生产者就停止生产,直到有消费者拿走数据。此时消费者拿走一条数据,生产者就生产一条数据。



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325574778&siteId=291194637