生产者消费者问题:生产者不能在容器满了继续生成,消费者不能在容器为空的时候消费
用户进程可以通过操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥、进程同步。信号量是一个变量来表示系统中某种资源的数量。
原语:是一种特殊的程序段,其执行只能一气呵成,不可被中断。
p、v操作
p:
1.s-1
2. s-1>=0进程继续执行
3.s-1<0,进程阻塞进入等待队列,转进程调度
v
1.s+1
2.s+1>0进程继续执行
3.s+1<=0,则从该信号的等待队列中唤醒一等待进程,然后在返回原进程继续执行或转进程调度
int sem_init(sem_t *sem, int pshared, unsigned int value);
-功能:初始化信号量
-参数:
-sem:信号量变量的地址
-pshared:0用在线程间,非0用在进程间
-value:信号量中的值
int sem_destroy(sem_t *sem);
-功能:释放资源
int sem_wait(sem_t *sem);
-功能:对信号量加锁,调用一次对信号量的值-1,如果值为0,就阻塞
- int sem_trywait(sem_t *sem);
- -功能:尝试对信号量加锁,调用一次对信号量的值-1,如果值为0,不阻塞
- int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
- -功能:尝试对信号量加锁,调用一次对信号量的值-1,如果值为0,等待设置的时间
int sem_post(sem_t *sem);
功能:对信号量解锁,调用一次对信号量的值+1
- #include
- #include
- #include
- #include
- #include
-
- //创建一个互斥量
- pthread_mutex_t mutex;
- //创建两个信号量
- sem_t psem;
- sem_t csem;
-
- struct Node{
- int num;
- struct Node *next;
- };
- struct Node *head;
- void *producer(void *arg){
- //创建新的节点,添加到链表中
- while(1){
- sem_wait(&psem);
- pthread_mutex_lock(&mutex);
- struct Node * newNode = (struct Node*)malloc(sizeof(struct Node));
- newNode->next=head;
- head=newNode;
- newNode->num=rand()%1000;
- printf("add node, num %d,tid :%ld\n",newNode->num,pthread_self());
- pthread_mutex_unlock(&mutex);
- sem_post(&csem);
- }
- }
-
- void *customer(void *arg){
- while(1){
- sem_wait(&csem);
- pthread_mutex_lock(&mutex);
- struct Node *tmp=head;
- head=head->next;
- printf("del node, num:%d,tid:%ld\n",tmp->num,pthread_self());
- free(tmp);
- pthread_mutex_unlock(&mutex);
- sem_post(&psem);
- }
- }
- //头节点
- struct Node * head = NULL;
-
- int main(){
- pthread_mutex_init(&mutex,NULL);
- sem_init(&psem,0,8);
- sem_init(&csem,0,0);
-
-
- //创建五个生产者线程和五个消费者线程
- pthread_t ptids[5],ctids[5];
- for(int i=0;i<5;i++){
- pthread_create(&ptids[i],NULL,producer,NULL);
- pthread_create(&ctids[i],NULL,customer,NULL);
- }
-
- for(int i=0;i<5;i++){
- pthread_detach(ptids[i]);
- pthread_detach(ctids[i]);
- }
-
- while(1){
- sleep(10);
- }
-
- pthread_mutex_destroy(&mutex);
- sem_destroy(&psem);
- sem_destroy(&csem);
- pthread_exit(NULL);
- return 0;
- }