线程同步
设计并实现一个计算线程与一个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\n",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\n",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操作-14 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 }
---运行结果: