收藏 分销(赏)

linux高级编程.doc

上传人:xrp****65 文档编号:7027076 上传时间:2024-12-25 格式:DOC 页数:11 大小:76.50KB
下载 相关 举报
linux高级编程.doc_第1页
第1页 / 共11页
linux高级编程.doc_第2页
第2页 / 共11页
点击查看更多>>
资源描述
///////////////////////// 第三天 线程 基本使用方法 ///////////////////////////////////////////////////////////// 二、线程 1.基本概念 线程 :是一个独立的指令流,是在某个进程中被创建的。它生存在进程资源 拥有独立的控制流,随进程的关闭而关闭 指令流:即代码段,独立是指独立于进程 进程:进程是执行程序的过程,拥有完整的资源。即进程有自已的数据段、堆栈段、代码段 即进程是运行的程序 进程    系统中程序执行和资源分配的基本单位    每个进程有自己的数据段、代码段和堆栈段    在进行切换时需要有比较复杂的上下文切换 线程    减少处理机的空转时间,支持多处理器以及减少上下文切换开销, 比创建进程小很多    进程内独立的一条运行路线    处理器调度的最小单元,也称为轻量级进程 可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享 线程   线程相关的执行状态和存储变量放在线程控制表内   一个进程可以有多个线程,有多个线程控制表及堆栈寄存器,共享一个用户地址空间 2.线程函数 #include <pthread.h> 1)创建线程 int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg); restrict thread :线程的ID号 指针类型,创建完的线程ID写入在这个参数 restrict attr :线程的属性是结构体 pthread_attr_t的指针 用来设置 start_routine :是线程函数的指针,也是线程函数的入口点,创建后马上执行线程函数。 即把输入的实参(函数)当作了独立的指令流 restrict arg :参数列表 用于等待线程的结束,是一个阻塞函数 int pthread_join(pthread_t thread, void **value_ptr); thread : 线程的ID value_ptr:线程的返回值 编译时,必须引入-lpthread 库 gcc -o test test.c -lpthread void* run(void* a){ char *p=(char *)a; int i=0; while(i<10){ printf("thread--------run %d\n",i++); sleep(1); } } int main(int argc,char **argv){ pthread_t tid; char buf[256]="aaa"; pthread_create(&tid,NULL, run,(void*)buf); pthread_join(tid,NULL); } 2)跳出线程的方式 关键点在于结束线程的函数 (1)从线程内用return 跳出线程,线程结束,函数的结束就是线程的结束 (2)在线程内调用pthread_exit函数 void pthread_exit(void *value_ptr) value_ptr是线程的返回值 (3)从线程外面调用pthread_cancel函数 int pthread_cancel(pthread_t thread); thread是线程ID 例: 11 void *thr_fn1(void *arg){ 12 return (void*)23;//用return跳出线程 13 } 14 void *thr_fn2(void *arg){ 15 pthread_exit((void*)24); 16 } 17 void *thr_fn3(void *arg){ 18 while(1) sleep(1); 19 } 20 21 22 int main(int argc,char **argv){ 23 void *tret; 24 pthread_t tid1,tid2,tid3; 25 pthread_create(&tid1,NULL,thr_fn1,NULL); 26 pthread_join(tid1,&tret); 27 printf("---1 %d\n",tret); 28 pthread_create(&tid2,NULL,thr_fn2,NULL); 29 pthread_join(tid2,&tret); 30 printf("---2 %d\n",tret); 31 pthread_create(&tid3,NULL,thr_fn3,NULL); 32 pthread_cancel(tid3); 33 pthread_join(tid3,&tret); 34 printf("---3 %d\n",tret); 35 36 return 0; 37 } 3)线程属性设置 pthread_attr_t attr; //定义结构的变量 pthread_init(&attr); //对属性结构进行初始化,通过函数对结构进行初始化 pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//添加属性 pthread_create(&tid1,&attr,thr_fn1,NULL); pthread_atrr_destroy(&attr); //销毁属性 ... pthread_join(tid1); 《练习》用QT编写wav音频播放器 思考的问题: 1.如何能自动读取出采样大小、频率、声道,而不需要输入 2.如何在播放时可以让界面正常,且可以点击其它按钮并停止 3.播放器应该包括哪些操作 《练习》用qt及线程编写wav播放器 //********************************** //mplay.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <linux/soundcard.h> #include <unistd.h> #include <QDebug> #define READSIZE 80 struct FILE_FRM{ pthread_t tid; //线程id long fd; //文件描述符 long start; //声频的起始位置 short channels; //声道 0单声道,1双声道 short format; //采样格式 8位, 16位 short speed; //频率 8k 11.025k 12k 22.05k 37.8k 44.1k long size; //音频数据的大小 long pos; //播放位置 } file_frm={0,0,0,0,0,0,0,0}; static int isstop=0; static int ispause=0; static FUN_STATE audio_setstate=NULL; /* state 1 开始运行, 0 结束 2 代表传送的是 pos 3 代表总长度值 4 暂停 */ //-------------------------------------------------------------------- void audio_set(FUN_STATE *fun){ audio_setstate=fun; } void audio_setvol(int lvol,int rvol){ int fd=open("/dev/mixer",O_RDWR); short vol=(lvol<<8 | rvol); //音量,用16位整数记录左右声道音量 ioctl(fd,MIXER_WRITE(SOUND_MIXER_VOLUME),&vol);//设音量 close(fd); } void audio_getvol(int *lvol,int *rvol){ int fd=open("/dev/mixer",O_RDWR); short vol; ioctl(fd,MIXER_READ(SOUND_MIXER_VOLUME),&vol);//读音量 *lvol= vol >>8; *rvol= vol & 0xFF; close(fd); } static int fileopen(char *filename){ char buf[256]={0}; file_frm.fd=open(filename,O_RDONLY); if (file_frm.fd==-1){ printf("---------- open file err\n"); return -1; } file_frm.start=0x28+4; //即头长44 //读文件格式 lseek(file_frm.fd,0x08,0); read(file_frm.fd,buf,4); if (strcmp(buf,"WAVE")!=0){ qDebug("file is not WAV\n"); close(file_frm.fd); file_frm.fd=0; return -1; } //读声道 lseek(file_frm.fd,0x16,0); read(file_frm.fd,&file_frm.channels,2);//使用时需要-1 //读频率 lseek(file_frm.fd,0x18,0); read(file_frm.fd,&file_frm.speed,2); //采样格式 lseek(file_frm.fd,0x22,0); read(file_frm.fd,&file_frm.format,2); //音频数据长度 不包括头长 lseek(file_frm.fd,0x28,0); read(file_frm.fd,&file_frm.size,4); return 0; } void *_play(void *val){ isstop=0; ispause=0; struct FILE_FRM *filefrm=(struct FILE_FRM *)val; //读取音频文件头信息**************************** //------------------------ qDebug("fd=%d,channels=%d,bits=%d,speed=%d",filefrm->fd,filefrm->channels,filefrm->format,filefrm->speed); char buf[256]={0}; //打开设备 int dsp_fd=open("/dev/dsp",O_RDWR); if (dsp_fd==-1) { qDebug("dsp open err\n"); return (void*)-2; } ioctl(dsp_fd,SNDCTL_DSP_STEREO,&filefrm->channels); ioctl(dsp_fd,SNDCTL_DSP_SETFMT,&filefrm->format); ioctl(dsp_fd,SNDCTL_DSP_SPEED,&filefrm->speed); /* state 1 开始运行, 0 结束 2 代表传送的是 pos 3 代表总长度值 4 暂停 */ audio_setstate(1,0); //开始运行 //S=R(采样频率Hz )×D(录音时间)×r(量化位数(位)) ×声道数/8 //S: 字节; R:HZ; D:录音时间S; r:量化位数bit //D=Size/(R*r*c/8); //t=size/(44100*8*2/8); //或 WAV文件的字节数/每秒=采样频率(Hz)×量化位数(位) ×声道数/8 //s=44100*8*2/8; //s是速度 //t=size/s; audio_setstate(3,filefrm.size/(filefrm.speed * filefrm.format *filefrm.channels/8)); //音频数据长度 for(filefrm.pos=0;filefrm.pos < filefrm.size;){ audio_setstate(2,filefrm.pos/(filefrm.speed * filefrm.format *filefrm.channels/8)); //播放位置 if(isstop) break; while (ispause) { audio_setstate(4,0);//暂停 usleep(50000); } int len=read(filefrm.fd,buf,READSIZE); write(dsp_fd,buf,len); filefrm.pos+=len; } audio_setstate(0,0); //结束 printf("play over\n"); close(dsp_fd); close(filefrm.fd); filefrm.fd=0; return 0; } void audio_play(char *buf){ if (fileopen(char *filename)!=0) return; pthread_create(&tid,NULL,&_play,(void*)buf); } void audio_stop(){ if (filefrm.fd <=0) return; isstop=1; if (tid!=0){ pthread_join(tid,NULL); tid=0; } if (filefrm.fd>0){ close(filefrm.fd); filefrm.fd=0; } } void audio_pause(){ if (filefrm.fd <=0) return; ispause=1; } void audio_replay(){ if (filefrm.fd <=0) return; ispause=0; audio_setstate(1,0); //开始运行 } void audio_playfrom(int pos){//从指定位置播放 if (filefrm.fd <=0) return; ispause=1; filefrm.pos=pos>filefrm.size?filefrm.size:pos; qDebug("---- new pos %d",wavpos); lseek(filefrm.fd,filefrm.pos+filefrm.start,0); ispause=0; } void audio_fastpre(int diff){//快进 if (filefrm.fd <=0) return; audio_playfrom(filefrm.pos-diff); } void audio_fastnex(int diff){//快退 if (filefrm.fd <=0) return; audio_playfrom(filefrm.pos+diff); } //********************************** //mplay.h #ifndef PLAY_H #define PLAY_H typedef void (*FUN_STATE)(int state,int val); extern void audio_play(char *buf); extern void audio_replay(); extern void audio_pause(); extern void audio_stop(); extern void audio_playfrom(int pos); extern void audio_fastpre(int diff); extern void audio_fastnex(int diff); extern void audio_getvol(int *lvol,int *rvol); extern void audio_setvol(int lvol,int rvol); extern void audio_set(FUN_STATE *fun); #endif // PLAY_H //************************************ //frmmain.cpp Filerw *pw; void statefun(int state,int val){ if (state==3) //音频数据大小 timeLd->setMaximum(val); else if(state==2) //播放位置状态显示 timeLd->setValue(val); else if (state==4){//暂停状态 pauseBtn->setEnabled(false); playBtn->setEnabled(true); } else if (state==1){ //播放状态 ui->pauseBtn->setEnabled(true); ui->playBtn->setEnabled(false); ui->nextBtn->setEnabled(true); ui->preBtn->setEnabled(true); ui->stopBtn->setEnabled(true); } else if(state==0){ //停止状态 pauseBtn->setEnabled(false); playBtn->setEnabled(true); nextBtn->setEnabled(false); preBtn->setEnabled(false); stopBtn->setEnabled(false); timeLd->setValue(0); } } Filerw::init(){ } Filerw::Filerw(QWidget *parent) : QWidget(parent) { init();//创建组件 code=QTextCodec::codecForLocale(); pw= this; audio_set(statefun); int lvol,rvol; audio_getvol(&lvol,&rvol); volSLd->setValue((lvol+rvol)/2); // statefun(0,0); } Filerw::~Filerw() { } void Filerw::on_playBtn_clicked() { //播放 if (isplaying==0){ if (fileName=="") return; char *file=code->fromUnicode(fileName).data(); audio_play(file); } else if (ispause==1){ audio_replay(); } } void Filerw::on_pauseBtn_clicked() { audio_pause(); } void Filerw::on_openBtn_clicked() { fileName = QFileDialog::getOpenFileName(this, code->toUnicode("打开音频文件"), "/home/", code->toUnicode("音频文件 (*.wav *.mp3 *.wma)")); ui->fileLb->setText(fileName); } void Filerw::on_volSl_valueChanged(int value) { audio_setvol(value); } void Filerw::on_timeLd_sliderMoved(int position) { audio_pause(); sliderpos=position; } void Filerw::on_timeLd_sliderReleased() { if (sliderpos!=0 && isplaying==1){ audio_playfrom(sliderpos); qDebug("position=%d",sliderpos); sliderpos=0; } if (ispause==1) audio_replay(); } void Filerw::on_preBtn_clicked() { audio_fastpre(ui->timeLd->maximum()/20); } void Filerw::on_nextBtn_clicked() { audio_fastnex(ui->timeLd->maximum()/20); } void Filerw::on_stopBtn_clicked() { audio_stop(); } void Filerw::on_exitBtn_clicked() { close(); }
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服