Unix-Linux编程实践教程——第十四章
来源:互联网 发布:iphonex预约软件 编辑:程序博客网 时间:2024/06/05 06:54
章节概要
本章节介绍线程机制以及多线程编程注意的同步问题
hello_single.c
/*********************************************************** > File Name: hello_single.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 12时03分28秒 **********************************************************/#include<stdio.h>#include<unistd.h>#define NUM 5void print_msg(char * msg){ for(int i=0;i<NUM;++i){ printf("%s",msg); fflush(stdout); sleep(1); }}int main(){ print_msg("hello"); print_msg("world\n");}
hello_multi.c
编译命令:gcc -o hello_multi hello_multi.c -lpthread
/********************************************************** > File Name: hello_multi.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 12时03分28秒 *********************************************************/#include<stdio.h>#include<pthread.h>#include<unistd.h>#define NUM 5void* print_msg(char * msg){ for(int i=0;i<NUM;++i){ printf("%s",msg); fflush(stdout); sleep(1); } return NULL;}int main(){ pthread_t t1,t2; pthread_create(&t1,NULL,print_msg,(void*)"hello"); pthread_create(&t2,NULL,print_msg,(void*)"world\n"); //pthread_join()函数,以阻塞的方式等待thread指定的线程结束。 //当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。 //并且thread指定的线程必须是joinable的。 pthread_join(t1,NULL); pthread_join(t2,NULL);}
incrprint.c
/******************************************************** > File Name: incrprint.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 13时21分43秒 ********************************************************/#include<stdio.h>#include<pthread.h>#include<unistd.h>#define NUM 5int counter = 0;void *print_count(void *m){ for(int i=0;i<NUM;++i){ printf("count=%d\n",counter); sleep(1); } return NULL;}int main(){ pthread_t t1; int i; pthread_create(&t1,NULL,print_count,NULL); for(i=0;i<NUM;++i){ counter++; sleep(1); } pthread_join(t1,NULL);}
twordcount1.c
/*********************************************************** > File Name: twordcount1.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 13时30分49秒 *********************************************************/#include<stdio.h>#include<pthread.h>#include<ctype.h>#include<stdlib.h>int total_words;//开两个线程分别统计两个文件的字符串数void* count_words(void* f){ char *filename = (char*)f; FILE *fp; int c,prevc = '\0'; if((fp=fopen(filename,"r"))!=NULL){ while((c=getc(fp))!=EOF){ if(!isalnum(c)&&isalnum(prevc)) total_words++; prevc = c; } fclose(fp); }else{ perror(filename); } return NULL;}int main(int ac,char *av[]){ pthread_t t1,t2; if(ac!=3){ printf("usage: %s file1 file2\n",av[0]); exit(1); } total_words = 0; pthread_create(&t1,NULL,count_words,(void*)av[1]); pthread_create(&t2,NULL,count_words,(void*)av[2]); pthread_join(t1,NULL); pthread_join(t2,NULL); printf("%5d:total words\n",total_words); return 0;}
twordcount2.c
/********************************************************* > File Name: twordcount2.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 13时30分49秒 **********************************************************/#include<stdio.h>#include<pthread.h>#include<ctype.h>#include<stdlib.h>int total_words;//互斥锁变量pthread_mutex_t counter_lock = PTHREAD_MUTEX_INITIALIZER;void* count_words(void* f){ char *filename = (char*)f; FILE *fp; int c,prevc = '\0'; if((fp=fopen(filename,"r"))!=NULL){ while((c=getc(fp))!=EOF){ if(!isalnum(c)&&isalnum(prevc)){ //加锁 pthread_mutex_lock(&counter_lock); total_words++; //解锁 pthread_mutex_unlock(&counter_lock); } prevc = c; } fclose(fp); }else{ perror(filename); } return NULL;}int main(int ac,char *av[]){ pthread_t t1,t2; if(ac!=3){ printf("usage: %s file1 file2\n",av[0]); exit(1); } total_words = 0; pthread_create(&t1,NULL,count_words,(void*)av[1]); pthread_create(&t2,NULL,count_words,(void*)av[2]); pthread_join(t1,NULL); pthread_join(t2,NULL); printf("%5d:total words\n",total_words); return 0;}
twordcount3.c
/********************************************************** > File Name: twordcount3.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 13时30分49秒 ******************************************************/#include<stdio.h>#include<pthread.h>#include<ctype.h>#include<stdlib.h>struct arg_set{ char *fname; int count;};void* count_words(void* a){ struct arg_set *args = (struct arg_set*)a; FILE *fp; int c,prevc = '\0'; if((fp=fopen(args->fname,"r"))!=NULL){ while((c=getc(fp))!=EOF){ if(!isalnum(c)&&isalnum(prevc)){ args->count++; } prevc = c; } fclose(fp); }else{ perror(args->fname); } return NULL;}int main(int ac,char *av[]){ pthread_t t1,t2; struct arg_set args1,args2; if(ac!=3){ printf("usage: %s file1 file2\n",av[0]); exit(1); } args1.fname = av[1]; args1.count = 0; pthread_create(&t1,NULL,count_words,(void*)&args1); args2.fname = av[2]; args2.count = 0; pthread_create(&t2,NULL,count_words,(void*)&args2); pthread_join(t1,NULL); pthread_join(t2,NULL); printf("%5d: %s\n",args1.count,av[1]); printf("%5d: %s\n",args2.count,av[2]); printf("%5d:total words\n",args1.count+args2.count); return 0;}
twordcount4.c
/******************************************************** > File Name: twordcount4.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 13时30分49秒 ********************************************************/#include<stdio.h>#include<pthread.h>#include<ctype.h>#include<stdlib.h>struct arg_set{ char *fname; int count;};struct arg_set *mailbox;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//条件变量pthread_cond_t flag = PTHREAD_COND_INITIALIZER;void* count_words(void* a){ struct arg_set *args = (struct arg_set*)a; FILE *fp; int c,prevc = '\0'; if((fp=fopen(args->fname,"r"))!=NULL){ while((c=getc(fp))!=EOF){ if(!isalnum(c)&&isalnum(prevc)){ args->count++; } prevc = c; } fclose(fp); }else{ perror(args->fname); } printf("COUNT:waiting to get lock\n"); pthread_mutex_lock(&lock); printf("COUNT:have lock,storing data\n"); //pthread_cond_wait 使线程挂起直到另一个线程通过条件变量发生消息 //该函数总是和互斥锁一起使用 //首先自动释放指定的锁,然后等待条件变量的变化 //调用此函数之前,必须上锁 if(mailbox!=NULL) pthread_cond_wait(&flag,&lock); mailbox = args; printf("COUNT: raising flag\n"); //通过条件变量flag发消息,若没有线程等候消息,则什么都不发生,若多个线程都在等待,只唤醒他们中的一个。 pthread_cond_signal(&flag); printf("COUNT: unlocking box\n"); pthread_mutex_unlock(&lock); return NULL;}int main(int ac,char *av[]){ pthread_t t1,t2; struct arg_set args1,args2; int reports_in = 0; int total_words = 0; if(ac!=3){ printf("usage: %s file1 file2\n",av[0]); exit(1); } pthread_mutex_lock(&lock); args1.fname = av[1]; args1.count = 0; pthread_create(&t1,NULL,count_words,(void*)&args1); args2.fname = av[2]; args2.count = 0; pthread_create(&t2,NULL,count_words,(void*)&args2); while(reports_in<2){ printf("MAIN: waiting for flag to go up\n"); pthread_cond_wait(&flag,&lock); printf("MAIN: Wow! flag was raised, I have the lock\n"); printf("%7d: %s\n",mailbox->count,mailbox->fname); total_words += mailbox->count; if(mailbox==&args1) pthread_join(t1,NULL); if(mailbox==&args2) pthread_join(t2,NULL); mailbox = NULL; pthread_cond_signal(&flag); reports_in++; } printf("%5d:total words\n",total_words); return 0;}
bounce1d.c
/****************************************************** > File Name: bounce1d.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 15时04分13秒 *********************************************************/#include<stdio.h>#include<curses.h>#include<pthread.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#define MESSAGE "HELLO"int row;int col;int dir;int delay;void* moving_msg(char* msg){ while(1){ usleep(delay*1000); move(row,col); addstr(msg); refresh(); col += dir; if(col<=0&&dir==-1) dir=1; else if(col+(int)strlen(msg)>=COLS&&dir==1) dir=-1; }}int main(){ int ndelay; int c; pthread_t msg_thread; initscr(); crmode(); noecho(); clear(); row = 10; col = 0; dir = 1; delay = 200; if(pthread_create(&msg_thread,NULL,moving_msg,MESSAGE)){ fprintf(stderr,"error creating thread"); endwin(); exit(0); } while(1){ ndelay = 0; c = getch(); if(c=='Q') break; if(c==' ') dir = ~dir; if(c=='f'&&delay>2) ndelay = delay/2; if(c=='s') ndelay = delay*2; if(ndelay>0) delay = ndelay; } pthread_cancel(msg_thread); endwin();}
tanimate.c
/********************************************************* > File Name: tanimate.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月19日 星期四 15时36分01秒 ********************************************************/#include<stdio.h>#include<curses.h>#include<pthread.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#define MAXMSG 10#define TUNIT 20000struct propset{ char *str; int row; int delay; int dir;};pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;void *animate(void* arg){ struct propset* info = (struct propset*)arg; int len = strlen(info->str)+2; int col = rand()%(COLS-len-3); while(1){ usleep(info->delay*TUNIT); pthread_mutex_lock(&mx); move(info->row,col); addch(' '); addstr(info->str); addch(' '); move(LINES-1,COLS-1); refresh(); pthread_mutex_unlock(&mx); col += info->dir; if(col<=0&&info->dir==-1) info->dir=1; else if(col+len>=COLS&&info->dir==1) info->dir=-1; } return NULL;}int setup(int nstrings,char* strings[],struct propset props[]){ int num_msg = (nstrings>MAXMSG?MAXMSG:nstrings); int i; srand(getpid()); for(i=0;i<num_msg;++i){ props[i].str = strings[i]; props[i].row = i; props[i].delay = 1+(rand()%15); props[i].dir = ((rand()%2)?1:-1); } initscr(); crmode(); noecho(); mvprintw(LINES-1,0,"'Q' to quit,'0'..'%d' to bounce",num_msg-1); return num_msg;}int main(int ac,char *av[]){ int c; pthread_t thrds[MAXMSG]; struct propset props[MAXMSG]; int num_msg; int i; if(ac==1){ printf("usage:tanimate string..\n"); exit(1); } num_msg = setup(ac-1,av+1,props); for(i=0;i<num_msg;++i){ if(pthread_create(&thrds[i],NULL,animate,&props[i])){ fprintf(stderr,"error creating thread"); endwin(); exit(0); } } while(1){ c = getch(); if(c=='Q') break; if(c==' '){ for(i=0;i<num_msg;++i){ props[i].dir = -props[i].dir; } } if(c>='0'&&c<='9'){ i = c-'0'; if(i<num_msg) props[i].dir = -props[i].dir; } } //通过锁暂停所有线程 pthread_mutex_lock(&mx); for(i=0;i<num_msg;++i){ pthread_cancel(&thrds[i]); } endwin(); return 0;}
阅读全文
0 0
- Unix-Linux编程实践教程——第十四章
- Unix-Linux编程实践教程——第二章
- Unix-Linux编程实践教程——第三章
- Unix-Linux编程实践教程——第四章
- Unix-Linux编程实践教程——第五章
- Unix-Linux编程实践教程——第六章
- Unix-Linux编程实践教程——第七章
- Unix-Linux编程实践教程——第八章
- Unix-Linux编程实践教程——第九章
- Unix-Linux编程实践教程——第十章
- Unix-Linux编程实践教程——第十一章
- Unix-Linux编程实践教程——第十二章
- Unix-Linux编程实践教程——第十三章
- Unix-Linux编程实践教程——第十五章
- Unix/Linux编程实践教程
- Unix/Linux编程实践教程
- Unix-linux编程实践教程
- Unix/Linux 编程实践教程 第6章 笔记
- PHP命名空间(Namespace)的使用浅析
- Python源码剖析(02 Python对象初探)
- 第8周项目4-稀疏矩阵的三元组表示的实现及应用(2)
- 记录SQL查询左连接,和Where的一次坑
- MFC网络编程(二):简单TCP通信
- Unix-Linux编程实践教程——第十四章
- 基于spring事务简单实例
- 有关前台自动压枪的更新检测
- Fork/Join 框架
- YOLO V2 的mAP数据测试
- c++派生类向基类转换的可访问性
- 二叉树的递归算法应用
- TCP流量控制和拥塞控制
- canvas学习一之canvas的基本使用