利用curses库来实现字符界面的改变,利用多线程实现每个字符的改变
设计思想:以整个屏幕为背景,随机生成26个字母以及每个字母初始的x,y值以及speed速度值,通过改变字符的y值,清屏并重绘,来实现字符的滑屏效果
最初线程设计思想:创建26个线程,每个线程控制一个字母,线程函数中根据y值清屏并重绘字符,对重绘过程采用互斥量加锁,由于清屏操作也会涉及到线程同步,故实现较为麻烦。
改进线程设计技巧:26个线程每个线程控制一个字母的属性更新(y值),单独创建一个线程,每隔10毫秒对所有26个字母根据y值进行重绘更新。
尽量把需要多个线程访问的共享资源改为一个线程去访问
#include <pthread.h>
#include <curses.h>
#include <math.h>
struct AChar
{
int x; //x坐标
int y; //y坐标
int speed; //速度
char a; //字符
};
int stop = 1;
pthread_t t[26]; //控制字母属性更新线程
pthread_t tid; //更新界面线程
pthread_mutex_t m;
struct AChar a[26];
void* run(void *d)
{
int id;
static idx = -1;
idx++;
id = idx;
while(stop)
{
pthread_mutex_lock(&m);
//改变对象y坐标
a[id].y += a[id].speed;
if(a[id].y >= LINES)
{
a[id].y = rand()%(LINES/4);
}
pthread_mutex_unlock(&m);
sched_yield();
usleep(10000);
}
}
void* update(void *d)
{
int i = 0;
while(stop)
{
erase();//清屏
for(i=0; i<26; i++)
{
mvaddch(a[i].y, a[i].x, a[i].a);
}
refresh();
usleep(10000);
}
}
main()
{
int i;
initscr();
curs_set(0); //隐藏光标
noecho(); //无回显
keypad(stdscr, TRUE);
for(i=0; i<26; i++)
{
a[i].x = rand()%COLS;
a[i].y = rand()%(LINES/4);
a[i].speed = 1+rand()%3;
a[i].a = 65+rand()%26;
}
pthread_mutex_init(&m, 0);
pthread_create(&tid, 0, update, 0);
for(i=0; i<26; i++)
{
//随机产生字母与位置
pthread_create(&t[i], 0, run, 0);
}
getch();
stop = 0;
for(i=0; i<26; i++)
{
pthread_join(t[i],(void**)0);
}
pthread_join(tid,(void**)0);
pthread_mutex_destroy(&m);
endwin();
}