<<ICE CREAM>>
关于pthread相关函数基本内容,查看下面的文章
重点补充:pthread_join(pthread_t threadl,void **rval_ptr);这个函数主要用在保证创建的线程可以被执行完,主程序在退出。
建设由主程序创建线程a,在主程序中执行pthread_join(a,NULL)主程序会在线程a执行完毕后,主程序在退出,避免因为时间片的切换,导致主程序执行完毕直接推出,而线程还没有执行完已经因为主程序的推出,而不能继续执行,主程序会被阻塞在该语句处,不能继续执行,直到线程a执行完毕,主程序在继续执行。
关于semaphore 相关内容参考下面文章
关于讲解 icecream的视频 http://open.163.com/movie/2008/1/6/5/M6SL23BRS_M6SL3BD65.html
实现代码:
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#define NUM_CUSTOMESS 10
struct ManCler {
int Result;
sem_t Request ;
sem_t Finished;
sem_t Lock;
} Mess_Man_Cler;
/*struct ManCler Mess_Man_Cler;
Mess_Man_Cler.Result = 0 ;
sem_init(&(Mess_Man_Cler.Request),0,0);
sem_init(&(Mess_Man_Cler.Finshed),0,0);
sem_init(&(Mess_Man_Cler.Lock),0,1);
*/
struct CashCustom{
int n ;
sem_t Request ;
sem_t Customsequence[NUM_CUSTOMESS];
sem_t Lock;
}Cash_Custom;
/*Cash_Custom.n = 0;
sem_init(&(Cash_Custom.Requst),0,0);
//sem_init(&Cash_Custom.ClerkFinish,0,0);
sem_init(&(Cash_Custom.Lock),0,1);
for (int i = 0 ; i < NUM_CUSTOMESS ; i++)
{
sem_init(&(Cash_Custom.Customsequencd)+i,0,0);
}
*/
void* manager(void * TotalCustom);
void* customes(void * NumIceCream);
void* clerk(void*ClerkFinished);
void* cashier();
void Initial();
void Initial(){
Mess_Man_Cler.Result = 0 ;
sem_init(&(Mess_Man_Cler.Request),0,0);
sem_init(&(Mess_Man_Cler.Finished),0,0);
sem_init(&(Mess_Man_Cler.Lock),0,1);
Cash_Custom.n = 0;
sem_init(&(Cash_Custom.Request),0,0);
sem_init(&(Cash_Custom.Lock),0,1);
for (int i = 0 ; i < NUM_CUSTOMESS ; i++)
{
sem_init(&(Cash_Custom.Customsequence[i]),0,0);
}
}
void* customes(void * NumIceCream)
{
int place;
sem_t ClerkFinished;
sem_init(&(ClerkFinished),0,0);
int p = *(int*)NumIceCream;
printf("cusomes:all number of ice cream %d\n",p);
for (int i = 0; i < p; i++)
{
//char c[32] ;
//sprintf(c,"clerk %d",i);
pthread_t a;
pthread_create(&a,NULL,clerk,(void *)(&ClerkFinished));
}
printf("custom:i employ all clerk\n");
for (int i = 0;i < p ; i++ ) sem_wait(&ClerkFinished);//这句话是等待clerk完成相关功能,即等待p个clerk都完成相关功能,每个clerk完成一次功能后,for循环由被阻塞的状态变成可以执行一次,然后继续被阻塞,p个 clerk完成相关功能后。for循环执行完毕。
printf("custome :i get all the ice cream");
sem_destroy(&ClerkFinished);
sem_wait(&(Cash_Custom.Lock));
place = Cash_Custom.n++;
sem_post(&(Cash_Custom.Lock));
sem_post(&(Cash_Custom.Request));
sem_wait(&(Cash_Custom.Customsequence[place]));
printf("cusome:i finished my shopping\n");
}
void*cashier()
{
for (int i = 0;i < NUM_CUSTOMESS;i++)
{
sem_wait(&(Cash_Custom.Request));
printf("cashier:%d is checked\n",i);
sem_post(&(Cash_Custom.Customsequence[i]));
}
}
void* manager(void * TotalCustom)
{
int TotalNumber = *(int*)TotalCustom;
int approve = 0;
while (approve < TotalNumber)
{
sem_wait(&(Mess_Man_Cler.Request));
Mess_Man_Cler.Result = rand()%2;
if (Mess_Man_Cler.Result == 1) approve += 1;
printf("manager:manager finshed check\n");
sem_post(&Mess_Man_Cler.Finished);
}
printf("manage:exit()");
}
void* clerk(void * ClerkFinished)
{
int p = 0;// used to descipe the initail stata of the Result
while(p != 1)
{
printf("clerk:clerk finins a ice cream\n");
sem_wait(&(Mess_Man_Cler.Lock));
sem_post(&(Mess_Man_Cler.Request));
sem_wait(&(Mess_Man_Cler.Finished));
p = Mess_Man_Cler.Result;
sem_post(&(Mess_Man_Cler.Lock));
}
sem_post((sem_t*)(ClerkFinished));
printf("clerk:clerk finished the ice cream\n");
}
int main(){
Initial();
int TotalIceCream = 0;//record the number of the ice cream needed by allclerk
int NumIceCream[NUM_CUSTOMESS] ;
for (int i = 0; i < NUM_CUSTOMESS;i++)
{
NumIceCream[i] = rand()%4 + 1;
}
pthread_t ArrayCustom[NUM_CUSTOMESS];//the name of thread custom
pthread_t P_Manager = 0;//the name of thread mamager
pthread_t P_Cashier = 0;//the name of thread cashier
for(int i = 0;i < NUM_CUSTOMESS;i++){
//NumIceCream = rand()%4+1;
pthread_create(ArrayCustom+i,NULL,customes,(void*)(NumIceCream+i));
TotalIceCream += NumIceCream[i];
printf("%d ice cream\n", NumIceCream[i]);
}
printf("totalNumbes:%d\n",TotalIceCream);
pthread_create(&P_Manager,NULL,manager,(void*)&TotalIceCream);
pthread_create(&P_Cashier,NULL,cashier,NULL);
//printf("99999");
for(int i;i < NUM_CUSTOMESS;i++)
{
pthread_join(ArrayCustom[i],NULL);
}
pthread_join(P_Manager,NULL);
pthread_join(P_Cashier,NULL);
}