1.条件变量:
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <stdio.h>
- #include <string.h>
- /*链表作为公享数据,需被互斥量保护*/
- #define SIZE 100
- int repository[SIZE]={0};//定义仓库大小,并初始化为0
- /*静态初始化一个条件变量和一个互斥量*/
- pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
- pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
- int empty_repository(int arr[])
- {
- int i,sum=0;
- for(i=0;i<SIZE;i++)
- {
- sum += arr[i];
- }
- return sum;
- }
- int fill_repository(int arr[])
- {
- int i,sum;
- for(i=0;i<SIZE;i++)
- {
- if(arr[i]==0)
- {
- arr[i]= rand() % 1000 + 1;
- printf("-------fill a[%d]=%d\n",i,arr[i]);
- return arr[i];
- }
- }
- return -1;
- }
- int del_repository(int arr[])
- {
- int i,temp;
- for(i=SIZE;i>=0;i--)
- {
- if(arr[i]!=0)
- {
- temp=arr[i];
- printf("-------del a[%d]=%d\n",i,arr[i]);
- arr[i]= 0;
- return temp;
- }
- }
- return -1;
- }
- void *consumer(void *p)
- {
- for (;;)
- {
- int ret=pthread_mutex_lock(&lock);
- if(ret !=0)
- {
- printf("consumer mutex_lock err:%s\n",strerror(ret));
- }
- while (!empty_repository(repository))
- {
- //如果条件不满足,释放锁,并阻塞在此处
- //如果条件满足,重新加锁,并解除阻塞,进行循环条件判断
- printf("cond_wait test mask\n");
- pthread_cond_wait(&has_product, &lock);
- }
- //模拟消费掉一个产品
- ret=del_repository(repository);
- if(ret==-1)
- {
- printf("del_repository() err\n");
- pthread_exit(NULL);
- }
- pthread_mutex_unlock(&lock);
- printf("-Consume %lu---Produce id=%d\n", pthread_self(), ret);
- sleep(rand() % 5);
- }
- }
- void *producer(void *p)
- {
- for (; ;)
- { //sleep(5),为验证consumer线程中的,pthread_cond_wait()会进行解锁+阻塞功能
- sleep(5);
- //生产者拿锁成功,再生产产品
- int ret=pthread_mutex_lock(&lock);
- if(ret !=0)
- {
- printf("producer mutex_lock() err:%s\n",strerror(ret));
- pthread_mutex_unlock(&lock);
- break;//跳出循环
- }
- //模拟生产一个产品
- ret=fill_repository(repository);
- if(ret==-1)
- {
- printf("fill_repository() err\n");
- pthread_mutex_unlock(&lock);
- break;
- // pthread_exit(NULL);//生产仓库满后,无法继续生产,退出生产线程
- }
- pthread_mutex_unlock(&lock);
- printf("-producer %lu---Produce id=%d\n", pthread_self(), ret);
- pthread_cond_signal(&has_product); //条件满足了,通知等待条件变量has_product的线程
- usleep(100000);
- }
- }
- int main(int argc, char *argv[])
- {
- pthread_t tid01, tid02,tid03;
- srand(time(NULL));
- pthread_create(&tid01, NULL, producer, NULL);
- pthread_create(&tid02, NULL, consumer, NULL);
- // pthread_create(&tid03, NULL, consumer, NULL);
- pthread_join(tid01, NULL);
- pthread_join(tid02, NULL);
- // pthread_join(tid03, NULL);
- return 0;
- }
-
4.信号量:
概念:信号量,是相对折中的一-种处理方式,既能保证同步,数据不混乱,又能提高线程并发。
基本操作:
操作函数:
- #include
- #include
- #include
- #include
- #include
- #define NUM 5
- int queue[NUM];//全局数组实现环形队列
- sem_t blank_number, product_number ;//空格子信号量,产品信号量
- void *producer(void *arg)
- {
- int i=0;
- while (1)
- {
- sem_wait(&blank_number);//生产者将空格子数-- ,为0则阻塞等待
- queue[i] = rand() % 1000 + 1;//生产一个产品
- printf("----Produce---%d\n",queue[i]);
- sem_post(&product_number);//将产品数++
- i=(i+1)%NUM;//借助下标实现环形
- sleep( rand()%1);
- }
- }
- void *consumer(void *arg)
- {
- int i=0;
- while (1)
- {
- sem_wait(&product_number);//消费者将产品数--,为则阻塞等待
- printf("-Consume---%d\n" , queue[i]);
- queue[i] = 0;//消费一个产品
- sem_post(&blank_number);//消费掉以后,将空格子数++
- i = (i+1) % NUM;
- sleep(rand( )%3);
- }
- }
- int main(int argc, char *argv[])
- {
- pthread_t pid, cid;
- sem_init(&blank_number, 0, NUM); //初始化线程间共享-0,空格子信号量为5,
- sem_init(&product_number, 0,0);//初始化线程间共享-0,产品数为0
- pthread_create(&pid, NULL, producer, NULL);
- pthread_create(&cid, NULL, consumer, NULL);
- pthread_join(pid, NULL);
- pthread_join(cid, NULL);
- sem_destroy(&blank_number );
- sem_destroy(&product_number);
- return 0;
- }