目次
4. system-V セマフォと POSIX セマフォの違い (named-sem と unnamed-sem)
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;
}