13. オペレーティング システム - posix セマフォ (名前のないセマフォ)

目次

1. 名前なしセマフォの紹介

第二に、セマフォステップの使用

 3、sem_init、sem_destroy

4. system-V セマフォと POSIX セマフォの違い (named-sem と unnamed-sem)

5. コード

1. 名前なしセマフォの紹介

有名なセマフォのスレッドはメモリ空間を共有するため、プロセス内のスレッド間の同期相互排除を解決するには、より軽量なメモリ ベースの (ファイル システム内ではない) 名前のないセマフォを使用する必要があります。

第二に、セマフォステップの使用

1. これらのスレッドがアクセスできる領域にこの変数 (グローバル変数など) を定義し、型は sem_t です。

2. スレッドが使用する前に、sem_init( ) で初期化します。

3. sem_wait( )/sem_trywait( ) および sem_post( ) を使用して、P 操作と V 操作をそれぞれ実行します。

4. 不要になったら、sem_destroy( ) を使用して彼を破壊します。

 3、sem_init、sem_destroy

 名前のないセマフォは通常、プロセス内のスレッド間で使用されるため、pshared パラメータは通常 0 です。このようなセマフォをプロセス間で使用する場合は、共有メモリなど、各プロセスがアクセスできる場所に定義する必要があります。

4. system-V セマフォと POSIX セマフォの違い (named-sem と unnamed-sem)

1. sys-V セマフォは比較的古く、構文が難しい。POSIX セマフォはシンプルで軽量です。

2. sys-V セマフォは、複数のリソースを表す複数のセマフォ要素に対してアトミック P/V 操作を同時に実行できます。POSIX セマフォは、一度に 1 つのセマフォしか操作できません。

3. sys-V セマフォと named-sem はシステム全体のリソースであり、プロセスが消滅した後も存在し続けます。一方、unnamed-sem はプロセス全体のリソースであり、プロセスの終了とともに消滅します。

4. sys-V セマフォの P/V 操作は、セマフォ要素に 1 より大きい値を加算または減算できますが、POSIX セマフォの各 P/V 演算は 1 を加算または減算します。

5. sys-V セマフォは元に戻す操作もサポートします。プロセスが sys-V セマフォで P/V 操作を実行すると、元に戻す必要がある操作にラベルを付けることができます。プロセスが終了すると、システムは自動的に元に戻します。それら マーキングの操作を行います。POSIX シグナルにはこの機能がありません。

6. Sys-V セマフォと named-sem は、プロセス間の相互排除の同期に適しています。unnamed-sem は、スレッド間の相互排除の同期に適しています。

一般に、system-V のセマフォは強力すぎて肥大化してしまいますが、実際の作業でそれらの高度な機能を必要としない場合は、インターフェースが明確でロジックが単純な POSIX セマフォを使用することをお勧めします。

5. コード

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

// 定义线程间共享的资源
sem_t sem ;

// 定义一个指针作用与线程之间的共享内存
char  * mem_map = NULL ;

void * FUNCTION(void * arg)
{
    // 由于接收到的arg 是 void 型的, 因此先进行强转
    char * msg = (char *)arg ;
    
    printf("线程号:%ld , 收到参数为:%s \n" , pthread_self() , msg );

    while(1)
    {   
        sem_wait(&sem) ;  
        printf("msg : %s \n" , mem_map) ;  
        sem_post(&sem);
        usleep(1000);//要有延时
    }
}

int main(int argc, char const *argv[])
{
    // 划分一个用于线程间通信的共享内存
    mem_map = calloc(1, 32) ;//申请一片32字节的内存


    //  初始化无名信号量信号量  0 表示线程间, 1 表示初始化资源量为1 
    if(sem_init( &sem , 0 , 1 ))
    {
        perror("sem init error");
        return -1 ;
    }
    
    // 创建线程
    pthread_t  thread;
    pthread_create(&thread, NULL, FUNCTION , "Hello GZ2123");

    while(1)
    {
        // P 操作, 等待获取资源
        sem_wait(&sem) ;
                
        fgets(mem_map , 32 , stdin) ;//获取数据
                
        sem_post(&sem);//释放资源
        usleep(1000);
    }
    return 0;
}

 

おすすめ

転載: blog.csdn.net/weixin_45981798/article/details/129881950