Linux 线程示例

原创 2007年10月06日 22:53:00
Linux 线程示例,原程序摘自Bruce Molay 的<<Understanding Unix/Linux Programing >>中第十四章的twordcount.c程序,将原来只能用两个线程为两个文件计数扩展为用三个线程为三个文件计数.
程序使用一个条件变量flag,一个互斥锁lock和一个全局变量mailbox来协同三个计数线程同时对三个文件的词数进行计数.主线程需要flag来指示mailbox中有消息,计数线程需要lock来协调对mailbox的写权限,并检查mailbox为空时才可覆盖.
在原来的程序中计数线程使用pthread_cond_wait来检测mailbox是否为空,若只是单纯的增加线程进行扩展,会造成死锁,主线程和计数线程都在等待flag条件变量,必须将其修改为释放lock和再要求lock才不会造成死锁:
修改段如下:
原来:
if ( mailbox != NULL ){
        printf(
"COUNT: oops..mailbox not empty. wait for signal ");
        pthread_cond_wait(
&flag,&lock);
}

修改为:
while(mailbox != NULL) {        // if the mailbox is not empty,wait
        pthread_mutex_unlock(&lock);
        pthread_mutex_lock(
&lock);
        
// pthread_cond_wait(&flag,&lock);
}
不可只是将if改为while应付了事.原来的用两个线程处理两个文件的程序最好也改用此段代码.

切记:
pthread_cond_wait(&flag,&lock); 释放lock,并等待flag,等到获得flag后会自动等待lock,之后再返回调用函数处.

完整程序:
/*******************************************************************
 * twordcount.c - thread word counter for two files
 * condition variable allows counter fuctions 
 *     to report result early
 
*/

#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<pthread.h>
#include 
<ctype.h>

struct arg_set {                // two values in one arg
    char *fname;                // file to examine
    int count;                // number of words
    int thread_id;                // thread id
}
;

struct arg_set *mailbox;
pthread_mutex_t 
lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t flag 
= PTHREAD_COND_INITIALIZER;

int main(int argc,char *argv[]) {
    pthread_t t1,t2,t3;
    
struct arg_set args1,args2,args3;    // two threads
    void *count_words(void *);        // two argsets
    int reports_in = 0;
    
int total_words = 0;

    
if(argc != 4{
        fprintf(stderr,
"Usage: %s file1 file2 file3 ",argv[0]);
        exit(
1);
    }


    pthread_mutex_lock(
&lock);        // lock the report box now
    
    args1.fname 
= argv[1];
    args1.count 
= 0;
    args1.thread_id 
= 1;
    pthread_create(
&t1,NULL,count_words,(void *)&args1);

    args2.fname 
= argv[2];
    args2.count 
= 0;
    args2.thread_id 
= 2;
    pthread_create(
&t2,NULL,count_words,(void *)&args2);

    args3.fname 
= argv[3];
    args3.count 
= 0;
    args3.thread_id 
= 3;
    pthread_create(
&t3,NULL,count_words,(void *)&args3);

    
while(reports_in < 3{
        printf(
"MAIN: waiting for flag to go up ");
        pthread_cond_wait(
&flag,&lock);    // wait for notify
        printf("MAIN: Wow!flag was raised, I have the lock ");
        printf(
"%7d: %s ",mailbox->count,mailbox->fname);
        total_words 
+= mailbox->count;
        
        
if(mailbox == &args1)
            pthread_join(t1,NULL);
        
if(mailbox == &args2)
            pthread_join(t2,NULL);
        
if(mailbox == &args3)
            pthread_join(t3,NULL);
        mailbox 
= NULL;
        pthread_cond_signal(
&flag);
        
++reports_in;
    }

    printf(
"%7d: total word ",total_words);

    
return 0;
}


void *count_words(void *a) {
    
struct arg_set *args = a;        // casts arg back to correct type
    FILE *fp;
    
int c,id = args->thread_id,prevc = '';

    
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%d: waiting to get lock ",id);
    pthread_mutex_lock(
&lock);        // get the mailbox
    printf("COUNT%d: have lock,storing data ",id);
    
while(mailbox != NULL) {        // if the mailbox is not empty,wait
        pthread_mutex_unlock(&lock);
        pthread_mutex_lock(
&lock);
        
// pthread_cond_wait(&flag,&lock);
    }

    mailbox 
= args;                // put ptr to our args there
    printf("COUNT%d: rasing flag ",id);
    pthread_cond_signal(
&flag);        // raise the flag
    printf("COUNT%d: unlocking box ",id);
    pthread_mutex_unlock(
&lock);        // release the mail box

    
return NULL;
}

 原书的两计数线程处理两文件程序:
/* twordcount4.c - threaded word counter for two files.    
 *         - Version 4: condition variable allows counter
 *                            functions to report results early 
 
*/


#include  
<stdio.h>
#include  
<pthread.h>
#include  
<ctype.h>

struct arg_set {        /* two values in one arg*/
        
char *fname;    /* file to examine    */
        
int  count;    /* number of words    */
}
;

struct arg_set  *mailbox = NULL;
pthread_mutex_t 
lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  flag 
= PTHREAD_COND_INITIALIZER;

main(
int ac, char *av[])
{
    pthread_t      t1, t2;        
/* two threads */
    
struct arg_set args1, args2;    /* two argsets */
    
void           *count_words(void *);
    
int            reports_in = 0;
    
int           total_words = 0;

    
if ( ac != 3 ){
        printf(
"usage: %s file1 file2 ", av[0]);
        exit(
1);
    }

    pthread_mutex_lock(
&lock);    /* lock the report box now */

    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 ");
        pthread_cond_wait(
&flag, &lock); /* wait for notify */
        printf(
"MAIN: Wow! flag was raised, I have the lock ");
        printf(
"%7d: %s ", 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);    /* announce state change */
        reports_in
++;
    }

    printf(
"%7d: total words ", total_words);
}

void *count_words(void *a)
{
    
struct arg_set *args = a;    /* cast arg back to correct type */
    FILE 
*fp;
    
int  c, prevc = '';
    
    
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 ");
    pthread_mutex_lock(
&lock);    /* get the mailbox */
    printf(
"COUNT: have lock, storing data ");
    
if ( mailbox != NULL ){
        printf(
"COUNT: oops..mailbox not empty. wait for signal ");
        pthread_cond_wait(
&flag,&lock);
    }

    mailbox 
= args;            /* put ptr to our args there */
    printf(
"COUNT: raising flag ");
    pthread_cond_signal(
&flag);    /* raise the flag */
    printf(
"COUNT: unlocking box ");
    pthread_mutex_unlock(
&lock);    /* release the mailbox */
    
return NULL;
}

linux 内核线程实例

~ # ps PID USER VSZ STAT COMMAND 1 root 868 S init 2 root 0 ...
  • suiyuan19840208
  • suiyuan19840208
  • 2012年12月28日 21:33
  • 2036

pthread_mutex_init()实例

百度百科链接介绍pthread_mutex_init()函数 [root@localhost cfile]# vim thread_mutex.c                      + t...
  • sonbai
  • sonbai
  • 2013年12月05日 15:06
  • 3076

linux多线程之自旋锁

基本概念: 何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,...
  • daiyudong2020
  • daiyudong2020
  • 2016年08月14日 00:17
  • 1236

VB.net 多线程实例

VB.NET(Visual Basic.NET)是为适应Microsoft .NET框架的需要,对Visual Basic进行了重大改造后的开发工具。它比Visual Basic 6.0功能更强大,更...
  • EricBai
  • EricBai
  • 2006年06月30日 10:13
  • 1288

最简单的线程并发例子

 用一个线程来实现这个功能1:变量i从0--40000来循环改变一个label1的值,值和i的值一样 然后不用线程也实现这个label2的显示功能2 如何把功能1和功能2同时进行?    1、建立主程...
  • Devillyd
  • Devillyd
  • 2006年11月06日 11:31
  • 1389

《线程》——多线程同步实例剖析

线程这个名词我们在学习操作系统的时候就接触过了,线程又称为轻量级进程,那进程是什么哪?大家可以跟随我的超链接看一下百度百科的解释。      简单线程实例,解决两个售票窗口售票问题。      具体的...
  • u013067402
  • u013067402
  • 2016年02月15日 08:16
  • 1505

无锁编程(三) - 忙等待

忙等待可以看作一种特殊的无锁编程,本文详细介绍了忙等待的概念,忙等待的分类,并给出使用方法和范例...
  • linux_bug
  • linux_bug
  • 2015年09月22日 17:36
  • 660

Android线程篇

在Android中,UI主线程并非线程安全的,所有UI相关的操作均需在UI主线程中完成。在默认情况下,开发者创建的Service、Activity、Broadcast均运行在UI主线程中,但将一些耗时...
  • u011014707
  • u011014707
  • 2015年06月20日 17:48
  • 1216

线程示例

这是个人学习时写的一些示例,仅供参考。如有错误,还望指正,谢谢!
  • shuxijing
  • shuxijing
  • 2017年11月17日 23:53
  • 15

linux 中线程的查看方式

在Linux中查看线程数的三种方法1、top -H 手册中说:-H : Threads toggle 加上这个选项启动top,top一行显示一个线程。否则,它一行显示一个进程。 2、ps xH ...
  • lijingshan34
  • lijingshan34
  • 2017年04月18日 12:06
  • 923
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux 线程示例
举报原因:
原因补充:

(最多只允许输入30个字)