操作系统经典同步互斥问题——生产者消费者问题
2014-10-17 00:00
519 查看
linux下的同步和互斥
tags:Linux
sync_mutex
Semaphore.h
一份好文档,胜读十年书本文参考了诸多资料,百度百科,cplusplus等
首先介绍一个头文件
#include <semaphore.h>
这里面包含了大多数的所需要使用的信号量.
包含:
int sem_init(sem_t *sem, int pshared, unsigned int value)
用于初始化信号量。
value代表信号量的初始值,
pshare代表信号量是进程内的线程共享,还是进程间共享。
对于Linux而言,就是子进程共享和父进程共享——Linux中不存在线程的问题,Linux中的线程,进程均为进程,只是看进程组,子进程父进程而已。对于进程关系,可以使用
pstree查看。
返回0时成功,返回-1时失败,并且设置errno 使用perror输出错误信息: - EINVAL value 超过 `SEM_VALUE_MAX` - ENOSYS pshared 非零,但系统还没有支持进程共享的信号量。
int sem_post(sem_t *sem)
这个函数相当于V操作,是一个"原子操作"——即是不会被打断(中断)的。并行计算中会出现的两个线
程同时对一个变量相加导致变量的值仅产生了一次变化在此处是不成立的。
返回0时成功,返回-1时失败, 并且设置errno:
EINVAL
sem 不是一个有效的信号量。
EOVERFLOW
信号量允许的最大值将要被超过。
int sem_wait(sem_t *sem)
这个函数相当于P操作,也是一个"原子操作"。等待对变量-1,如果不能对变量-1,则进入等待队列
int sem_trywait(sem_t *sem)
如果变量不能-1(即
sem_t为0),则不会进入等待队列,直接返回错误代码。
int sem_timedwait(sem_t *sem)
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
return 0 (success), return -1 (failure) and set errno:
EINTR
The call was interrupted by a signal handler; see signal(7).
//调用被信号处理中断
EINVAL sem is not a valid semaphore.
//sem不是有效的信号量
The following additional error can occur for sem_trywait():
//下面的错误是sem_trywait()可能发生的:
EAGAIN The operation could not be performed without blocking (i.e., the
semaphore currently has the value zero).
//除了锁定无法进行别的操作(如信号量当前是0值).
The following additional errors can occur for sem_timedwait():
//下面的错误是sem_timedwait()可能发生的:
EINVAL The value of abs_timeout.tv_nsecs is less than 0, or greater than or
equal to 1000 million.
//abs_timeout.tv_nsecs 的值比0小或者大于等于1000毫秒(译者注:纳秒的值不能比0小,不能比1秒大)
ETIMEDOUT
The call timed out before the semaphore could be locked.
//在信号量锁定之前就超时了
注意
对这些函数,信号处理程序总是会中断阻塞,不管是否使用了sigaction(2)的SA_RESTART标志位.
/*============================================================================= # # Author: svtter - svtter@qq.com # # QQ : 57180160 # # Last modified: 2014-10-03 20:35 # # Filename: producer_consumer.cc # # Description: # =============================================================================*/ #include <cstdio> #include <unistd.h> #include <semaphore.h> #include <pthread.h> #include <sys/types.h> #include <stdlib.h> #include <iostream> using namespace std; #define N 5 #define item int // P/V操作 void P(sem_t* sem) { if(sem_wait(sem)) perror("P error!"); } void V(sem_t* sem) { if(sem_post(sem)) perror("V error!"); } sem_t mutex; sem_t full; sem_t empty; item buffer ; int i = 0, j = -1; void init_sem() { sem_init(&mutex, 0, 1); sem_init(&full, 0, 0); sem_init(&empty, 0, N); } void* producer(void *arg) { int product; while(1) { //生成随机数字 product = rand()%100; // cout << "producer running..." << endl; P(&empty); P(&mutex); buffer[i] = product; printf("producer produced %d @ %d pos\n", product, i); i=(i+1)%N; V(&mutex); V(&full); sleep(1); } } void* consumer(void *arg) { int product, temp; while(1) { // cout << "consumer running..." << endl; P(&full); P(&mutex); j = (j+1)%N; product = buffer[j]; V(&mutex); V(&empty); printf("Consumer consumed %d @ %d pos\n", product, j); sleep(3); } } int main() { //random num srand(time(NULL)); init_sem(); int error; pthread_t producer_t, consumer_t; error = pthread_create(&producer_t, NULL, producer, NULL); if(error != 0) printf("error in create producer.\n"); else printf("create producer success!\n"); pthread_create(&consumer_t, NULL, consumer, NULL); if(error != 0) printf("error in create consumer.\n"); else printf("create consumer success!\n"); pthread_join(producer_t, NULL); pthread_join(consumer_t, NULL); return 0; }
相关文章推荐
- 经典生产者与消费者问题(线程的同步与互斥)
- 操作系统:经典进程同步问题(1)生产者-消费者问题
- Linux下生产者消费者问题详细分析(操作系统期中考试论文---并发程序的同步和互斥)
- 进程同步互斥经典题之消费者与生产者问题
- 【操作系统】经典教程同步问题 ---- 生产者和消费者
- 进程间同步互斥经典问题(一)生产者-消费者问题
- 进程间同步互斥经典问题(一)生产者-消费者问题
- 【操作系统总结】经典的进程同步问题-生产者消费者问题
- 三个同步与互斥问题之生产者与消费者
- 生产者-消费者问题实现 (linux下C同步信号量和互斥信号量的应用)
- 经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
- 经典同步问题--生产者和消费者
- 经典进程同步问题-生产者与消费者
- 经典同步问题(一)---生产者与消费者问题
- 操作系统经典同步互斥问题——生产者消费者问题
- 操作系统学习笔记(13) 互斥与同步的经典问题 -哲学家进餐问题
- 资源同步与互斥问题(生产者与消费者)
- 操作系统的一个经典问题 -- "生产者-消费者"问题
- 用C#线程技术模拟“生产者-消费者”经典进程同步问题
- 操作系统同步互斥经典问题——读者写者问题