加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

sem_t和pthread_condition_t的使用方法和区别

(2014-10-14 20:53:32)
标签:

股票

分类: Career
信号量(sem)与条件变量(cond)的主要差别在于,条件变量等待必须在发送之前,否则容易出现死锁,而信号量等待可以在发送之后执行。一句话概括信号量对于操作的时序没有要求。

From http://blog.csdn.net/kerwin_zxc/article/details/7877108

分类: linux C++ 2012-08-17 13:53 514人阅读 评论(0) 收藏 举报

pthread_cond_t

  1. #include   
  2. #include   
  3. #include   
  4.   
  5. struct msg  
  6.     struct msg *next;  
  7.     int num;  
  8. };  
  9.   
  10. struct msg *head NULL;  
  11. pthread_cond_t has_product PTHREAD_COND_INITIALIZER;  
  12. pthread_mutex_t lock PTHREAD_MUTEX_INITIALIZER;  
  13.   
  14. void *producer(void *p)  
  15.  
  16.     struct msg *mp;  
  17.     for(;;)  
  18.      
  19.         mp malloc(sizeof(struct msg));  
  20.         mp->num rand() 2000 1;  
  21.         printf("Producer  %d\n",mp->num);  
  22.         pthread_mutex_lock(&lock);  
  23.         mp->next head;  
  24.         head mp;  
  25.         pthread_mutex_unlock(&lock);  
  26.         pthread_cond_signal(&has_product);  
  27.         sleep(rand() 5);  
  28.      
  29.     return NULL;  
  30.  
  31.   
  32. void *consumer(void *p)  
  33.  
  34.     struct msg *mp;  
  35.     for(;;)  
  36.      
  37.         pthread_mutex_lock(&lock);  
  38.         while(head == NULL)  
  39.             pthread_cond_wait(&has_product,&lock);  
  40.         mp head;  
  41.         head mp->next;  
  42.         pthread_mutex_unlock(&lock);  
  43.         printf("Consumer %d\n",mp->num);  
  44.         free(mp);  
  45.         sleep(rand() 5);  
  46.           
  47.      
  48.     return NULL;  
  49.  
  50.   
  51.   
  52. int main()  
  53.  
  54.     pthread_t pid, cid;  
  55.     srand(time(NULL));  
  56.       
  57.     pthread_create(&pid,NULL,producer,NULL);  
  58.     pthread_create(&cid,NULL,consumer,NULL);  
  59.     pthread_join(pid,NULL);  
  60.     pthread_join(cid,NULL);  
  61.     return 0;  
  62.  

pthread_mutex_t
  1. #include   
  2. #include   
  3. #include   
  4.   
  5. #define NLOOP   50  
  6. int counter 0;  
  7. pthread_mutex_t counter_mutex PTHREAD_MUTEX_INITIALIZER;  
  8.   
  9. voiddoit(voidp)  
  10.  
  11.     int i,val;  
  12.     for0; NLOOP; i++)  
  13.      
  14.         pthread_mutex_lock(&counter_mutex);  
  15.         counter++;  
  16.         printf("%x: %d\n",(unsigned int)pthread_self(),counter);  
  17.         pthread_mutex_unlock(&counter_mutex);  
  18.         usleep(1);  
  19.      
  20.     return 0;  
  21.  
  22.   
  23. int main()  
  24.  
  25.     pthread_t tidA,tidB;  
  26.     pthread_create(&tidA,NULL,doit,NULL);  
  27.     pthread_create(&tidB,NULL,doit,NULL);  
  28.       
  29.     pthread_join(tidA,NULL);  
  30.     pthread_join(tidB,NULL);  
  31.       
  32.     return 0;  
  33.  

sem_t
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5.   
  6. #define NUM 5  
  7. int queue[NUM];  
  8.   
  9. sem_t blank_number, product_number;  
  10.   
  11. void *producer(void *p)  
  12.  
  13.     int 0;  
  14.     while(1)  
  15.      
  16.         sem_wait(&blank_number);  
  17.         queue[i] rand() 1000 1;  
  18.         sem_post(&product_number);  
  19.         printf("product %d\n",queue[i]);  
  20.         (i 1) NUM;  
  21.         sleep(rand() 5);  
  22.      
  23.     return NULL;  
  24.  
  25.   
  26. void *consumer(void *p)  
  27.  
  28.     int 0;  
  29.     while(1)  
  30.      
  31.         sem_wait(&product_number);  
  32.         printf("consumer %d\n",queue[i]);  
  33.         queue[i] 0;  
  34.         sem_post(&blank_number);  
  35.         (i+1) NUM;  
  36.         sleep(rand() 5);  
  37.      
  38.     return NULL;  
  39.  
  40.   
  41.   
  42. int main()  
  43.  
  44.     pthread_t pid,cid;  
  45.     srand(time(NULL));  
  46.     sem_init(&blank_number,0,NUM);  
  47.     sem_init(&product_number,0,0);  
  48.       
  49.     pthread_create(&pid, NULL, producer,NULL);  
  50.     pthread_create(&cid, NULL, consumer,NULL);  
  51.     pthread_join(pid,NULL);  
  52.     pthread_join(cid,NULL);  
  53.     sem_destroy(&blank_number);  
  54.     sem_destroy(&product_number);  
  55.     return 0;  
  56. }  

From http://www.cppblog.com/saha/articles/189802.html

基本接口介绍:
1.   pthread_create 

  #include

   int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);

   创建一个由调用线程控制的新的线程并发运行。新的线程使用start_routine作为实现体,并以arg作为第一个参数。
   新的线程可以通过调用pthread_exit显式结束,或者通过start_routine return来隐式结束。其中后者等价于调用pthread_exit并以start_routine 的返回值作为退出码。
      新线程的初始信号状态继承自他的创建线程,并且没有挂起的信号。pthread-win32暂时未实现信号量。
      attr参数指明新线程的属性,如果attr=NULL,则使用默认属性:新线程是joinable(not detached),和默认的调度策略(非实时)
     返回值:如果成功,新线程的指针会被存储到thread的参数中,并返回0。如果错误则一个非0的错误码返回。
      如果返回EAGAIN,没有足够的系统资源创建一个线程,或者已经存在大于PTHREAD_THREADS_MAX个活跃线程。

2. pthread_exit
   
#include
   void pthread_exit(void *retval);
  
pthread_exit结束调用线程的执行.所有通过pthread_cleanup_push设置的清除句柄将会被反序执行(后进先出)。
 所以key值非空的线程特定数据Finalization functions被调用(参见pthread_key_create)。
  最后调用线程被终止。
  retval是这个线程结束的返回值,可以通过在别的线程中调用pthread_join来获取这个值。
   没有返回值。

3. pthread_join 
   #include
   int pthread_join(pthread_t th, void **thread_return);   

   挂载一个在执行的线程直到该线程通过调用pthread_exit或者cancelled结束。
   如果thread_return不为空,则线程th的返回值会保存到thread_return所指的区域。
   th的返回值是它给pthread_exit的参数,或者是pthread_canceled 如果是被cancelled的。
   被依附的线程th必须是joinable状态。一定不能是detached通过使用pthread_detach或者pthread_create中使用pthread_create_detached属性。
   当一个joinable线程结束时,他的资源(线程描述符和堆栈)不会被释放直到另一个线程对它执行pthread_join操作。
   如果成功,返回值存储在thread_return中,并返回0,否则返回错误码:
   ESRCH:找不到指定线程
   EINVAL:线程th是detached或者已经存在另一个线程在等待线程th结束
   EDEADLK:th的参数引用它自己(即线程不能join自身)

4.pthread_cancel   

  #include
  int pthread_cancel(pthread_t thread);
  int pthread_setcancelstate(int state, int *oldstate);
  int pthread_setcanceltype(int type, int *oldtype);
  void pthread_testcancel(void);

   Cancellation是一种一个线程可以结束另一个线程执行的机制。更确切的说,一个线程可以发生Cancellation请求给另一个线程。
   根据线程的设置,收到请求的线程可以忽视这个请求,立即执行这个请求或者延迟到一个cancellation点执行。
   当一个线程执行Cancellation请求,相当于在那个点执行pthread_exit操作退出:所有cleanup句柄被反向调用,所有析构函数被调用结束线程并返回pthread_canceled.


5.pthread_cond   
   #include
   pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
   int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
   int pthread_cond_signal(pthread_cond_t *cond);
   int pthread_cond_broadcast(pthread_cond_t *cond);
   int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
   int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
   int pthread_cond_destroy(pthread_cond_t *cond);

   
pthread_cond_init初始化条件变量,通过cond_attr,如果cond_attr是null则使用默认属性。也可以通过常量PTHREAD_COND_INITIALIZER静态初始化。
   pthread_cond_signal激活一个正在等待条件变量cond的线程。如果没有线程在等待则什么也不会发生,如果有多个线程在等待,则只能激活一个线程,带未指定是哪个线程(根据操作系统自己的调度策略选择)。
   pthread_cond_broadcast激活所有在等待条件变量cond的线程。
   pthread_cond_wait自动解锁mutex(pthread_unlock_mutex)等待条件变量cond发送。线程的执行被挂起不消耗cpu时间直到cond发送。在wait的入口mutex必须被锁住。
   在重新回到线程前,pthread_cond_wait会重新获得mutex(pthread_lock_mutex).解锁mutex和挂起是自动进行的。因此,如果所有线程在发送cond前都申请mutex的话,
   这种wait的内部实现机制能够保证在线程锁住mutex和线程wait之间不会有cond发送操作发送。
   pthread_cond_timedwaitpthread_cond_wait,只是多了个超时设置,如果超时,则重新获取mutex并且返回ETIMEDOUT,时间为绝对时间。
   pthread_cond_destroy销毁一个条件变量。必须没有线程在wait该条件变量。
   condition函数是异步信号不安全的,容易产生死锁,必须自己控制调用流程避免死锁。

6.semaphore
 #include
 int sem_init(sem_t *sem, int pshared, unsigned int value);
 int sem_wait(sem_t * sem);
 int sem_timedwait(sem_t * semconst struct timespec *abstime);
 int sem_trywait(sem_t * sem);
 int sem_post(sem_t * sem);
 int sem_post_multiple(sem_t * sem, int number);
 int sem_getvalue(sem_t * sem, int * sval);
 int sem_destroy(sem_t * sem);

 sem_init:
初始化信号量,pshared表示该信号量是否只属于当前进程(pshared==0),如果pshared不为0则表示可以在进程间共享。value表示该信号量的初始值。
  sem_wait:如果信号量的值大于0,则自动减1并立即返回。否则线程挂起直到sem_post或sem_post_multiple增加信号量的值。
  sem_timedwait:同sem_wait,只是多了个超时设置,如果超时,首先将全局变量errno设为ETIMEDOUT,然后返回-1.
  sem_trywait:如果信号量的值大于0,将信号量减1并立即返回,否则将全局变量errno设为ETIMEDOUT,然后返回-1。sem_trywait不会阻塞。
  sem_post:释放一个正在等待该信号量的线程,或者将该信号量+1.
  sem_post_multiple:释放多个正在等待的线程。如果当前等待的线程数n小于number,则释放n个线程,并且该信号量的值增加(number - n).
  sem_get_value:返回信号量的值。在pthread-win32实现中,正值表示当前信号量的值,负值的绝对值表示当前正在等待该信号量的线程数。虽然在POSIX不需要这么表示,但是也是同样含义。


  信号量(sem)与条件变量(cond)的主要差别在于,条件变量等待必须在发送之前,否则容易出现死锁,而信号量等待可以在发送之后执行。一句话概括信号量对于操作的时序没有要求。

几个测试程序:
1.
#include 
#include 
#include "pthread.h"


pthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond PTHREAD_COND_INITIALIZER;

void *thread1(void *);
void *thread2(void *
);

int i=1
;
int main(void
)
{
    pthread_win32_process_attach_np();
    pthread_win32_thread_attach_np();

    pthread_t t_a;
    pthread_t t_b;

    pthread_create(&t_a,NULL,thread2,(void *)NULL);

    pthread_create(&t_b,NULL,thread1,(void *)NULL); 
    pthread_join(t_b, NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&
cond);

    pthread_win32_thread_detach_np();
    pthread_win32_process_detach_np();

    system("pause"
);
    return 0
;
}

void *thread1(void *
junk)
{
    for(i=1;i<=9;i++

    {
        
        if(i%3==0
)
        {
            pthread_mutex_lock(&mutex);

            pthread_cond_signal(&cond);
            pthread_mutex_unlock(&mutex);
        }
        
else        
            printf("thead1:%d\n"
,i);

    }

    return
 NULL;
}

void *thread2(void *
junk)
{
    while(i<9
)
    {
        
        if(i%3!=0
)
        {
            pthread_mutex_lock(&
mutex);
            pthread_cond_wait(&cond,&mutex);

            pthread_mutex_unlock(&mutex);
        }
        printf("thread2:%d\n"
,i);
        

    }

    return
 NULL;
}
#include 
#include 
#include "pthread.h"
#include 

typedef struct arg_set
{
    char *
fname;
    int
 count;
    int
 tid;
}ARG_SET;

bool bWait false
;
ARG_SET *mailbox =
 NULL;
pthread_mutex_t read_lock =
 PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t write_lock =
 PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t read_cond =
 PTHREAD_COND_INITIALIZER;
pthread_cond_t write_cond =
 PTHREAD_COND_INITIALIZER;


void main(int ac, char *
av[])
{
    pthread_win32_process_attach_np();
    pthread_win32_thread_attach_np();

    pthread_t t1, t2, t3;
    ARG_SET args1, args2, args3;
    void *count_words(void *
);
    int reports_in 0
;
    int total_words 0
;

    if (4 !=
 ac)
    {
        printf("usage: %s file1 file2 file3\n", av[0
]);
        return
;
    }
    
    args1.fname av[1
];
    args1.count 0
;
    args1.tid 1
;
    pthread_create(&t1, NULL, count_words, (void *)&
args1);

    args2.fname av[2
];
    args2.count 0
;
    args2.tid 2
;
    pthread_create(&t2, NULL, count_words, (void *)&
args2);

    args3.fname av[3
];
    args3.count 0
;
    args3.tid 3
;
    pthread_create(&t3, NULL, count_words, (void *)&
args3);

    while(reports_in 3
)
    {
        printf("MAIN: waiting for flag to go up\n"
);
        pthread_mutex_lock(&
read_lock);
        bWait true
;
        pthread_cond_wait(&read_cond, &
read_lock);
        bWait false
;
        pthread_mutex_unlock(&
read_lock);
        printf("MAIN: wow! flag was raised, have the lock\n"
);

        printf("MAIN: }: %s\n", mailbox->count, mailbox->
fname);
        total_words += mailbox->
count;

        Sleep(10
);

        printf("MAIN: Ok, I've read the thread %d mail\n", mailbox->
tid);
        
        pthread_mutex_lock(&
write_lock);
        pthread_cond_signal(&
write_cond);
        pthread_mutex_unlock(&
write_lock);
        printf("MAIN: raising write flag\n"
);

        reports_in++
;
    }
    printf("}: total words\n"
total_words);

    pthread_mutex_destroy(&
read_lock);
    pthread_mutex_destroy(&
write_lock);
    pthread_cond_destroy(&
read_cond);
    pthread_cond_destroy(&
write_cond);

    pthread_win32_thread_detach_np();
    pthread_win32_process_detach_np();

    system("pause"
);
}

void *count_words(void *
a)
{
    ARG_SET *args (ARG_SET*
)a;
    FILE *
fp;
    int c, prevc '\0'
;

    if (NULL != (fp fopen(args->fname, "r"
)))
    {
        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\n", args->
tid);    
    
    
    pthread_mutex_lock(&
write_lock);  
    if (NULL !=
 mailbox)
    {
        printf("COUNT %d: oops..mailbox not empty. wait for signal\n", args->
tid);
        pthread_cond_wait(&write_cond, &
write_lock);
    }

    printf("COUNT %d: OK, can write mail\n", args->
tid);
    mailbox =
 args;  

    
    while (!
bWait)
    {
        Sleep(1
);        
    }
    pthread_mutex_lock(&
read_lock); 
    pthread_cond_signal(&read_cond);    

    pthread_mutex_unlock(&read_lock); 

    printf("COUNT %d: raising read flag\n", args->
tid);


    pthread_mutex_unlock(&write_lock);    

    printf("COUNT %d: unlocking box\n", args->tid);    

    return
 NULL;
}
http://www.cppblog.com/Images/OutliningIndicators/None.gif#include 
http://www.cppblog.com/Images/OutliningIndicators/None.gif#include 
http://www.cppblog.com/Images/OutliningIndicators/None.gif#include "pthread.h"
http://www.cppblog.com/Images/OutliningIndicators/None.gif#include "semaphore.h"
http://www.cppblog.com/Images/OutliningIndicators/None.gif#include 
http://www.cppblog.com/Images/OutliningIndicators/None.gif
http://www.cppblog.com/Images/OutliningIndicators/None.giftypedef struct arg_set
http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif{
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    char *fname;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    int count;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    int tid;
http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif}
ARG_SET;
http://www.cppblog.com/Images/OutliningIndicators/None.gif
http://www.cppblog.com/Images/OutliningIndicators/None.gifARG_SET *mailbox NULL;
http://www.cppblog.com/Images/OutliningIndicators/None.gifstatic sem_t sem_write;
http://www.cppblog.com/Images/OutliningIndicators/None.gifstatic sem_t sem_read;
http://www.cppblog.com/Images/OutliningIndicators/None.gif
http://www.cppblog.com/Images/OutliningIndicators/None.gif
http://www.cppblog.com/Images/OutliningIndicators/None.gifvoid main(int ac, char *av[])
http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif{
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    pthread_win32_process_attach_np();
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    pthread_win32_thread_attach_np();
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    pthread_t t1, t2, t3;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    ARG_SET args1, args2, args3;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    void *count_words(void *);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    int reports_in 0;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    int total_words 0;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    if (4 != ac)
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif    {
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        printf("usage: %s file1 file2 file3\n", av[0]);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        return;
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif    }

http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    if (-1 == sem_init(&sem_read, 1)
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        || -1 == sem_init(&sem_write, 0, 0))
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif    {
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        return;
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif    }

http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args1.fname av[1];
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args1.count 0;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args1.tid 1;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    pthread_create(&t1, NULL, count_words, (void *) &args1);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args2.fname av[2];
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args2.count 0;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args2.tid 2;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    pthread_create(&t2, NULL, count_words, (void *) &args2);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args3.fname av[3];
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args3.count 0;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    args3.tid 3;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    pthread_create(&t3, NULL, count_words, (void *) &args3);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    while(reports_in 3)
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif    {
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        printf("MAIN: waiting for sub thread write\n");
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        sem_wait(&sem_write);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        printf("MAIN: }: %s\n", mailbox->count, mailbox->fname);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        total_words += mailbox->count;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        if mailbox == &args1) 
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif            pthread_join(t1,NULL);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        if mailbox == &args2) 
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif            pthread_join(t2,NULL);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        if mailbox == &args3) 
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif            pthread_join(t3,NULL);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        mailbox NULL;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        printf("MAIN: Ok,I have read the mail\n");
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        sem_post(&sem_read);  
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif        reports_in++;
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif    }

http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif   
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    printf("}: total words\n", total_words);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    sem_destroy(&sem_read);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    sem_destroy(&sem_write);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    pthread_win32_thread_detach_np();
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    pthread_win32_process_detach_np();
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    system("pause");
http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif}

http://www.cppblog.com/Images/OutliningIndicators/None.gif
http://www.cppblog.com/Images/OutliningIndicators/None.gif
http://www.cppblog.com/Images/OutliningIndicators/None.gifvoid *count_words(void *a)
http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif{
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif    struct arg_set *args (arg_set *)a;    
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    FILE *fp;
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    int  c, prevc '\0';
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif     
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif    if (fp fopen(args->fname, "r")) != NULL )
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif    {
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif         whilegetc(fp)) != EOF )
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif         {
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif               if !isalnum(c) && isalnum(prevc) )
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif               {
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif                    args->count++;
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif               }

http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif               prevc c;
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif         }

http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif         fclose(fp);
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif     }
 else 
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif          perror(args->fname);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif     printf("COUNT %d: waiting for main thread read the mail\n", args->tid);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif     sem_wait(&sem_read);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif     printf("COUNT %d:OK,I can write mail\n", args->tid);
http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif     mailbox args;            
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif     printf("COUNT %d: Finished writting\n", args->tid);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif     sem_post(&sem_write);
http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif     return NULL;
http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif}





0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有