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;}
原创粉丝点击