Linux learning - posix semaphore communication between processes use

1 Overview

Semaphore (semaphore) is a method of providing a synchronization between different processes or threads between the different given process. SystemV into POSIX semaphores and semaphore, here to learn POSIX semaphores.

POSIX semaphores is divided into well-known semaphores and semaphore memory (unnamed semaphore) based. The difference is whether you need to use POSIX IPC name to identify.

NOTE:Linux操作系统中,POSIX有名信号量创建在虚拟文件系统中 
一般挂载在/dev/shm,其名字以sem.somename的形式存在。

2. semaphore operation

As early learning operating system that would be, it is up to the semaphore PV operation, to sum up about what is going on:

P operations, also called waiting (the wait) a semaphore, the semaphore value will test the operation, if the value is less than or equal to zero, will the current process / thread is put to sleep when the semaphore after it becomes greater than 0 minus 1.
Pseudo code, this two-step operation must be atomic.

while(sem <=0);
sem--;

V operation, hang out (POST) an amount of a signal, the magnitude of the operation signal plus a
pseudo-code as follows:

sem++;

The size of the semaphore value is generally used to mean initializing the number of available resource (e.g., buffer size, after the code embodied); if initialized to 1, the value of the semaphore called two, two function value of the semaphore bit like a cross exclusion lock.

The difference is : mutex lock and unlock must be executed in the same thread, and the semaphore to hang out but do not have to perform the operation by the thread execution waiting.

3.POSIX semaphore related interfaces:

1.sem_init () initializes the semaphore unnamed

#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);

//pshared指定该信号量用于进程还是线程同步
//0-表示用于线程同步(所有线程可见)
//非0-表示用于进程同步(需要放在共享内存中)

2.sem_open () initialization famous semaphore

#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
Link with -pthread.
//套路跟之前的消息队列类似
//oflag可以设置为O_CREAT | O_EXCL (如果存在则返回错误)。
//mode可以设置为0644 自己可读写,其他用户和组内用户可读
//value表示信号量初始化的值

3.sem_wait () and sem_post () function waits and hanging out

#include <semaphore.h>
int sem_wait(sem_t *sem);//P操作
int sem_post(sem_t *sem);//V操作
Link with -pthread.

4.sem_timedwait () Timeout waiting

 int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
 //跟sem_wait()类似,不过,如果P操作不能立即执行,该函数将投入睡眠
 //并等待abs_timeout中指定的时间。
 //如果超时依旧无法执行P操作,则返回timeout错误

4.1 unnamed semaphore creation

sem_t sem;
...  ...
sem_init(&sem, 0, 0) == -1);

4.2 famous semaphore use


//有名信号量要指定一个名字somename,打开成功后
//将以sem.somename的形式存在于/dev/shm/目录下。 
//书中用二值信号量做互斥同步,这里我直接用mutex。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

#define MAXSIZE 10
void *produce(void *); 
void *consume(void *);

typedef void *(*handler_t)(void *);//线程函数指针

struct _shared 
{
    int buff[MAXSIZE];

    sem_t *nempty;
    sem_t *nstored;
};//共享缓冲
typedef struct _shared shared;
shared shared_;
pthread_mutex_t mutex;//互斥锁
int nitems;//生产和消费的数目

int main(int argc,char **argv)
{
    if (argc !=2)
    {
        printf("usage:namedsem <#items>\r\n");
        exit(-1);
    }
    nitems=atoi(argv[1]);
    const char *const SEM_NEMPTY = "nempty";//信号量的“名字”
    const char *const SEM_NSTORED = "nstored";//信号量的“名字”
    pthread_t tid_produce;//生产者线程 id
    pthread_t tid_consume;//消费者线程 id
    //初始化信号量和互斥锁
    pthread_mutex_init(&mutex, NULL); 
    shared_.nstored=sem_open(SEM_NSTORED,O_CREAT|O_EXCL,0644,0);
    shared_.nempty=sem_open(SEM_NEMPTY,O_CREAT|O_EXCL,0644,MAXSIZE);
    memset(shared_.buff,0x00,MAXSIZE);

    //线程创建
    handler_t handler=produce;
    pthread_setconcurrency(2);
    if((pthread_create(&tid_produce,NULL,handler,NULL))<0)
    {
        printf("pthread_create error\r\n");
        exit(-1);
    }
//    sleep(5);
    handler=consume;
    if((pthread_create(&tid_consume,NULL,handler,NULL))<0)
    {
        printf("pthread_create error\r\n");
        exit(-1);
    }

    //线程回收
    pthread_join(tid_produce,NULL);
    pthread_join(tid_consume,NULL);

    //信号量锁销毁
    sem_unlink(SEM_NEMPTY);
    sem_unlink(SEM_NSTORED);
    pthread_mutex_destroy(&mutex);
    exit(0);
}



void *produce(void *args)
{
    int i;
    for(i=0;i<nitems;i++)
    {
        sem_wait(shared_.nempty);
        pthread_mutex_lock(&mutex);
        shared_.buff[i%MAXSIZE]=i;
        printf("add an item\r\n");
        pthread_mutex_unlock(&mutex);
        sem_post(shared_.nstored);
    }
    return NULL;
}


void *consume(void *args)
{
    int i;
    for(i=0;i<nitems;i++)
    {
        sem_wait(shared_.nstored);
        pthread_mutex_lock(&mutex);
        printf("consume an item\r\n");
        if(shared_.buff[i%MAXSIZE]!=i)
            printf("buff[%d]=%d\r\n",i,shared_.buff[i%MAXSIZE]);
        pthread_mutex_unlock(&mutex);
        sem_post(shared_.nempty);
    }
    return NULL;
}

Item 2 ending

Item 1 Analysis Review

Red-black trees and red-black tree implementation map and set

And a lock mode and the use of semaphores posix

The first project

Guess you like

Origin blog.csdn.net/tonglin12138/article/details/93751861