1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > linux 生产者消费者 多进程 Linux多线程 生产者消费者算法和条件变量的使用

linux 生产者消费者 多进程 Linux多线程 生产者消费者算法和条件变量的使用

时间:2022-09-09 12:38:30

相关推荐

linux 生产者消费者 多进程 Linux多线程 生产者消费者算法和条件变量的使用

接着上一篇博文,原来双线程,现在为了实现 暂停/继续 功能,又加了一个线程。第三线程使用条件信号量,当用户按下S键,第三线程将检测到,并且将ifpause置为1,然后输出线程将在if语句成立后被条件信号量cond阻塞。

此时第三线程依然运行。

当检测到按下R后,ifpause置为0,并且使用条件信号量唤醒输出线程。

全局采用生产者/消费者算法。保证输出线程和从文件读数字的线程相互合作正确。

第三线程调用的函数kbhit(),前面一堆语句是为了设置终端,以实现输入字符无回显。#include

#include

#include

#include

#include

#include

#include

#include

void *kbhit();

void *thread_function(void *arg);

int worksize=10;

//char workarea[worksize];

char workarea[10];

sem_t sem;

sem_t full;

sem_t empty;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/

int in=0,out=0;

int ifpause=0;//0--can continue running 1--condition change! need pause

int main()

{

int res;

FILE *fp;

int ch;

pthread_t a_thread,hit_thread;

void *thread_result;

/semaphore init

res=sem_init(&sem,0,1);

if(res!=0)

{perror("error:");exit(1);}

res=sem_init(&full,0,0);

if(res!=0)

{perror("error:");exit(1);}

res=sem_init(&empty,0,worksize);

if(res!=0)

{perror("error:");exit(1);}

//(void)signal(SIG);

/kbhit//

res=pthread_create(&hit_thread,NULL,kbhit,NULL);

if(res!=0)

{perror("error:");exit(1);}

/creat thread///

res=pthread_create(&a_thread,NULL,thread_function,NULL);

if(res!=0)

{perror("error:");exit(1);}

/open file/

if((fp=fopen("/home/mirage/Desktop/program/pie.txt","r"))==NULL)

{perror("error:");exit(1);}

///producer-read from file

while(1)

{

sem_wait(&empty);

sem_wait(&sem); //critical

if((ch=fgetc(fp))==EOF)

break;

workarea[in]=ch;

in=(in+1)%worksize;//

sem_post(&sem); //no critical

sem_post(&full);

}//while

sem_destroy(&sem);

sem_destroy(&empty);

sem_destroy(&full);

pthread_mutex_destroy(&mutex);

exit(0);

}//main

///consumer-output to terminal

void *thread_function(void *arg)

{

int ent=0;

printf("pie=:3.\n");

while(1)

{

sem_wait(&full);

sem_wait(&sem); //critical

///

pthread_mutex_lock(&mutex);

if(ifpause==1)//need pause

pthread_cond_wait(&cond,&mutex);/*条件满足,需要等待,阻塞输出进程,之后生产者进程将在sem_wait(&sem)阻塞。*/

pthread_mutex_unlock(&mutex);

//

usleep(80000);

printf("%c",workarea[out]);

fflush(stdout);

ent++;

if(ent==10)

{printf("\n");ent=0;}

out=(out+1)%worksize;

sem_post(&sem); //no critical

sem_post(&empty);

}//while

}

/kbhit()//

void *kbhit()

{

struct termios oldt, newt;

int ch;

int oldf;

tcgetattr(STDIN_FILENO, &oldt);

newt = oldt;

newt.c_lflag &= ~(ICANON | ECHO);

tcsetattr(STDIN_FILENO, TCSANOW, &newt);

oldf = fcntl(STDIN_FILENO, F_GETFL, 0);

fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

//ch = getchar();

//tcsetattr(STDIN_FILENO, TCSANOW, &oldt);

//fcntl(STDIN_FILENO, F_SETFL, oldf);

while(1){

usleep(20000);

ch=getchar();

pthread_mutex_lock(&mutex);/*锁住互斥量*/

if(ch=='s')

{ifpause=1;}

else if(ch=='r'&&ifpause==1)//already pause but need run

{ ifpause=0;

pthread_cond_signal(&cond);/*条件改变,发送信号,通知输出线程*/

}

pthread_mutex_unlock(&mutex);/*解锁互斥量*/

///

}//while

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。