zoukankan      html  css  js  c++  java
  • 实验2-线程同步与通信

    线程同步

    设计并实现一个计算线程与一个I/O线程共享缓冲区的同步与通信, 程序要求:
    两个线程,共享公共变量a;
    线程1负责计算(1到100的累加,每次加一个数);
    线程2负责打印(输出累加的中间结果);
    主进程等待子线程退出。

    (1)采用读写锁来实现

      pthread_rwlock_t rwlock; 

      ---创建一把读写锁

      ---创建一个写的线程

      pthread_create(&ptid[0],NULL,writeNum,NULL); //写函数
        for(i = 1; i<= 100; i++) {
            pthread_rwlock_wrlock(&rwlock); //写锁
            num = num + i;
            pthread_rwlock_unlock(&rwlock); //释放锁资源
            sleep(1);
        }

      ---创建读线程 以及线程函数执行内容

      pthread_create(&ptid[1],NULL,readNum,NULL); //读函数
    while(1) {
            pthread_rwlock_rdlock(&rwlock); //加锁
            printf("--- read_number -> %d
    ",num);
            pthread_rwlock_unlock(&rwlock); //释放锁资源
            sleep(1);
    }

      ---回收读写线程

        pthread_join(ptid[0], NULL);
        pthread_join(ptid[1], NULL);

      ---结果:

     (2)采用信号灯实现

      ---创建信号灯

    1 semId = semget((key_t)IPC_PRIVATE,2,IPC_CREAT|0666); //
    2 if(semId == -1) {
    3     perror("semget failed");
    4     return 0;
    5 }

      --给信号灯赋值:上面我们创建了两个信号灯

    1 union semun un1, un2;
    2 un1.val = 0;
    3 if((semctl(semId,0,SETVAL,un1)) == -1) {
    4     perror("init un1 failed");
    5 }
    6 un2.val = 1;
    7 if((semctl(semId,1,SETVAL,un2)) == -1) {
    8     perror("init un2 failed");
    9 }

      ---创建两个进程:一个执行加i并写num操作,一个执行读num操作

    1 pthread_create(&ptid[0],NULL,(void *)writeNum,NULL); //写函数
    2 
    3 for(i = 1; i<= 100; i++) {
    4     P(semId, 1);
    5     num = num + i;
    6     V(semId, 0);
    7     sleep(0.6);
    8 }
    1 pthread_create(&ptid[1],NULL,(void *)readNum,NULL); //读函数
    2 
    3 while(1) {
    4     P(semId, 0);
    5     printf("--- read_number -> %d
    ",num);
    6     V(semId, 1);
    7     sleep(0.6);
    8 }

      ---P、V操作函数

    1 struct sembuf sem;    
    2 sem.sem_num = index; //信号量编号
    3 sem.sem_op = -1; //P操作-1
    4 sem.sem_flg = 0; //操作标记:0或IPC_NOWAIT等
    5 if(semop(semId,&sem,1) == -1){        
    6    //1:表示执行命令的个数
    7    perror("semp P operator failed");
    8    exit(1);
    9 }
    1 struct sembuf sem;    
    2 sem.sem_num = index;
    3 sem.sem_op =  1;
    4 sem.sem_flg = 0;
    5 if(semop(semId,&sem,1) == -1){        
    6         //1:表示执行命令的个数
    7         perror("semp V operator failed");
    8         exit(1);
    9 }

      ---运行结果:

  • 相关阅读:
    Python·安装扩展包的几种方法
    Arduino系列硬件资源介绍
    树莓派USB摄像头的使用
    树莓派frp服务器和客户端配置教程
    树莓派frp内网穿透
    用Windows远程桌面连接树莓派的方法
    控制窗体的位置和大小
    树霉派更换软件镜像源
    I2C的库函数应用示例
    I2C总线的Arduino库函数
  • 原文地址:https://www.cnblogs.com/fsmly/p/10071487.html
Copyright © 2011-2022 走看看