Posex信号量実現プロセス間の同期(生産者&消費者)


1 Posex信号量sem


#include
sem_t信号量のタイプ
int sem_init(sem_t *sem, int pshared, unsigned int value);
1)pshared=0は同じマルチスレッドの同期に使用される.
2)pshared>0が複数のプロセス間の同期に使用される場合、semは共有メモリに格納する必要があります.
最後にvalueは信号量の初期値である.
int sem_wait(sem_t *sem);
指定した信号量の値をテストします.その動作は原子です.
sem<=0 sem-1プロセススレッドをスリープ待機状態にし、呼び戻される
sem>0 sem-1プロセスを1つのリソースに取得して返します
int sem_post(sem_t *sem);
指定した信号量semの値に1を加算する.
呼醒は、信号量の任意のスレッド(存在する場合、sem<=0)を待っている.
共有メモリapi
共有スペースを作成するには、次の手順に従います.
int shmget(key,size,flag)
keyをフラグとしてsizeサイズの共有ストレージを設定し、flagはこのストレージのアクセス権である.
共有ストレージに対するプロセスのマッピング:
void* shmat(shmid,void *add,flag)
shmidはshmgetによって確立された共有ストレージブロックフラグであり、addはプロセスがどのアドレスを使用して共有ストレージのアドレスにマッピングするかを指定する(0に設定するとカーネルヘルプによって設定される).
共有ストレージのマッピングに使用されるプロセスの最初のアドレスを返します.このアドレスを使用すると、共有ストレージの操作が完了します.

二sem実装プロセスのp-v操作

semは複数のスレッドの反発を実現し、プロセス空間でsem_を定義するだけである.各スレッドがsem_を共有しているため、t変数でよい.t変数.同様に、semがプロセス間の反発を実現する場合、このsem_tの変数は共有ストレージで定義されます.なぜなら、2つのプロセスがsem_に対してtの動作は、情報同期を実現し、反発の目的を達成するために、同じアドレス空間の変数でなければならない.プロセス間のデータ共有は、共有ストレージで行えます.

三コード実装生産者-消費者

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/shm.h>

int main()
{
    int shmid;
    sem_t *sem_product,*sem_consume;// 

    // sem_t 
    if(shmid = shmget(IPC_PRIVATE,sizeof(sem_t)*2,0600))
        perror("shmget error:");
    if((sem_product = shmat(shmid,0,0600)))
        perror("shmat error:");
    sem_consume = &sem_product[1];

    // 
    if(sem_init(sem_consume,1,0))
        perror("sem_init error:");
    if(sem_init(sem_product,1,0))
        perror("sem_init error:");

    pid_t cpid;
    cpid = fork();
    printf("@fter fork
"); if(cpid == -1){ perror("fork error"); exit(0); } if(cpid == 0) { printf("@child
"); while(1){ sem_wait(sem_product); sleep(1); printf("pid:%d product...
",getpid()); sem_post(sem_consume); } } else{ printf("@parent
"); while(1) { sem_post(sem_product); sem_wait(sem_consume); printf("pid:%d consume...
",getpid()); } } }:

実行結果:
root@cloud2:~/slp/mylinuxcprogram# ./sem.out  shmget error::Success shmat error::Success @fter fork @parent @fter fork @child pid:25957 product... pid:25956 consume... pid:25957 product... pid:25956 consume...
...