信号的PV操作(同步和互斥的概念)

PV操作是一种实现进程互斥与同步的有效方法。PV操作与信号量的处理相关,P表示通过的意思,V表示释放的意思。

互斥和同步概念:

互斥指的是控制两个进度相互排斥,不能同时运行。

同步指的是控制两个进度让他有先后顺序,次序可控。

 

例子:生产者和消费者的关系,需要调用资源,用共享内存。

信号量

作用:用于保护线程或进程之间的共享资源与实现同步与互斥。

有名信号量

作用:用于保护共享内存,防止资源抢占和实现同步与互斥。

消费者
#include  <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>

int main()
{
     

    //创建一个信号量
    sem_t *s=sem_open("/mysem",O_CREAT,0777,1);
	 if(s != SEM_FAILED)
     {
         printf("创建信号量成功\n");
         
     }else 
     {
         perror("创建信号量失败\n");
     }

     sem_t *s1=sem_open("/mysem1",O_CREAT);
	 if(s1 != SEM_FAILED)
     {
         printf("创建信号量成功\n");
         
     }else 
     {
         perror("创建信号量失败\n");
     }


    //获取信号量的值 
    int sval=0;
    sem_getvalue(s,&sval);
    printf("s当前信号量的值 %d\n",sval);


      sval=0;
    sem_getvalue(s1,&sval);
    printf("s1当前信号量的值 %d\n",sval);


      
    //1.创建共享内存对象  
    key_t key=ftok("/",100);
         if(key < 0)
         {
            perror("create fail:");
            return -1;
         }

    //2.获取共享内存描述符  
    int shm_id = shmget(key,1024,IPC_CREAT|0777);
        if(shm_id < 0)
        {
            perror("shmget fail:");
            return -1;
        }

    //3.映射共享内存 
    int *p=shmat(shm_id,NULL,0);
   
 


    //处理数据 
    while (1)
    {
        //进行P 操作,申请资源 
        sem_wait(s);

         if(*p%2 == 0)
         {
            printf("处理偶数=%d\n",*p);
         }else 
         {
            printf("处理非偶数=%d\n",*p);
         }

        //释放S1 
        sem_post(s1);
    }

    //关闭信号量 
    sem_close(s);
    sem_close(s1);

    //销毁有名信号量 
    sem_unlink("/mysem");
    sem_unlink("/mysem1");


}
生产者
#include  <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>

int main()
{
     
   //创建一个信号量
    sem_t *s=sem_open("/mysem",O_CREAT,0777,1);
	 if(s != SEM_FAILED)
     {
         printf("创建信号量成功\n");
         
     }else 
     {
         perror("创建信号量失败\n");
     }

     sem_t *s1=sem_open("/mysem1",O_CREAT,0777,0);
	 if(s1 != SEM_FAILED)
     {
         printf("创建信号量成功\n");
         
     }else 
     {
         perror("创建信号量失败\n");
     }



    //获取信号量的值 
    int sval=0;
    sem_getvalue(s,&sval);
    printf("s当前信号量的值 %d\n",sval);


    sem_getvalue(s1,&sval);
    printf("s1当前信号量的值 %d\n",sval);


    //定义一个数据 
    int data=0;  
      
    //1.创建共享内存对象  
    key_t key=ftok("/",100);
         if(key < 0)
         {
            perror("create fail:");
            return -1;
         }

    //2.获取共享内存描述符  
    int shm_id = shmget(key,1024,IPC_CREAT|0777);
        if(shm_id < 0)
        {
            perror("shmget fail:");
            return -1;
        }

    //释放 s 
    sem_post(s); 
   
    //3.映射共享内存 
    int *p=shmat(shm_id,NULL,0);
    *p = data++;
    while (1)
    {

        //申请s1  
        sem_wait(s1);

        //不断生产数据 
        *p = data++; 
        printf("生产数据 %d\n",*p);

        //释放资源 
        sem_post(s); //V 操作 释放
    }

}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux中,可以使用信号量和PV原语操作机制实现进程的同步互斥。 1. 同步机制:可以使用信号量来实现进程的同步信号量是一种计数器,它用来控制多个进程对共享资源的访问。在Linux中,信号量由semget、semop和semctl三个系统调用来完成。 2. 互斥机制:可以使用PV原语操作机制来实现进程的互斥PV原语操作机制可以实现原子操作,保证多个进程对共享资源的访问是互斥的。在Linux中,PV原语操作机制由semaphore.h头文件中的sem_init、sem_wait和sem_post三个函数来实现。 下面是一个简单的示例代码: ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <semaphore.h> sem_t sem; // 定义信号量 void *thread_func(void *arg) { sem_wait(&sem); // 等待信号量 printf("Thread %d is running\n", *(int *)arg); sem_post(&sem); // 发送信号量 return NULL; } int main() { sem_init(&sem, 0, 1); // 初始化信号量 pthread_t tid[5]; int i; for (i = 0; i < 5; i++) { int *arg = malloc(sizeof(int)); *arg = i; pthread_create(&tid[i], NULL, thread_func, arg); // 创建线程 } for (i = 0; i < 5; i++) { pthread_join(tid[i], NULL); // 等待线程结束 } sem_destroy(&sem); // 销毁信号量 return 0; } ``` 在上面的示例代码中,我们使用了sem_wait和sem_post函数来实现线程的同步。在每个线程中,我们使用sem_wait函数等待信号量,当信号量的值为1时,线程可以继续执行。在线程执行完后,我们使用sem_post函数发送信号量,将信号量的值加1,以便其他线程可以继续执行。同时,我们使用sem_init函数初始化信号量,使用sem_destroy函数销毁信号量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值