pthread_cond_wait用法解析与案例

来源:互联网 发布:centos开mc服务器 编辑:程序博客网 时间:2024/06/05 15:22

pthread_cond_wait用法解析与案例

    pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)函数传入的参数mutex用于保护条件,因为我们在调用pthread_cond_wait时,如果条件不成立我们就进入阻塞,但是进入阻塞这个期间,如果条件变量改变了的话,那我们就漏掉了这个条件。因为这个线程还没有放到等待队列上,所以调用pthread_cond_wait前要先锁互斥量,即调用pthread_mutex_lock(),pthread_cond_wait在把线程放进阻塞队列后,自动对mutex进行解锁,使得其它线程可以获得加锁的权利。这样其它线程才能对临界资源进行 访问并在适当的时候唤醒这个阻塞的进程。当pthread_cond_wait返回的时候又自动给mutex加锁。

      pthread_cond_wait必须放  在pthread_mutex_lockpthread_mutex_unlock之间,因为他要根据共享变量的状态来决定是否要等待,而为了不永远等待下去所以必须要在lock/unlock队中 

以下为案例:

    实现多线程编程,主程序终端输入命令如:1,2,3,4等,线程send_pthread实现

将命令解析为cmd1,cmd2,cmd3,quit等,线程wake_pthread实现将命令写入文件新建文件中(如:log.txt)

要求:要用到线程同步与互斥机制

编译:./a.out pthead.c  -lpthread

调试结果:


 

  vi   log.txt




#include<stdio.h>#include <pthread.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>typedef struct _Linknode_{int data;struct _Linknode_ *next;}Linknode;Linknode *create_linknode(){Linknode *node = NULL;node = (Linknode *)malloc(sizeof(Linknode));node->next = NULL;return node;}int insert_linknode(Linknode *head,int data){Linknode *new = create_linknode();new->data = data;new->next = head->next;head->next = new;return 0;}int delete_linknode(Linknode *head){int value;Linknode *p = head->next;value = p->data;head->next = p->next;free(p);return value;}int  is_empty_linknode(Linknode *head){return (head->next == NULL) ?1:0;}pthread_mutex_t send_lock,wake_lock;pthread_cond_t  send_cond,wake_cond;char *content[] = {"cmd1","cmd2","cmd3","quit",NULL};int INDEX ;int init_pthread_lock(pthread_mutex_t *mutex_lock){int ret;ret = pthread_mutex_init(mutex_lock,NULL);if(ret != 0 ){fprintf(stderr,"fail to pthread_mutex_init\n");exit(EXIT_FAILURE);}return 0;}int init_pthread_cond(pthread_cond_t *cond){int ret ;ret = pthread_cond_init(cond,NULL);if(ret != 0){fprintf(stderr,"fail to pthread_cond_init\n");exit(EXIT_FAILURE);}return 0;}void *send_pthread(void *arg){int fd = *((int *)arg);while(1){pthread_cond_wait(&send_cond,&send_lock);write(fd,content[INDEX],strlen(content[INDEX]) );pthread_mutex_unlock(&send_lock);if(INDEX == 3)break;}pthread_exit(NULL);}void *wake_thread(void *arg){Linknode *L = (Linknode *)arg;while(1){if(is_empty_linknode)pthread_cond_wait(&wake_cond,&wake_lock);switch(delete_linknode(L)){case 1:INDEX = 0;break;case 2:INDEX = 1;break;case 3:INDEX = 2;break;case 4:INDEX = 3;goto next;}pthread_mutex_unlock(&wake_lock);pthread_mutex_lock(&send_lock);pthread_cond_signal(&send_cond);pthread_mutex_unlock(&send_lock);usleep(500);}next :pthread_cond_signal(&send_cond);pthread_exit(NULL);}int main(int argc, const char *argv[]){int fd;int cmd;int ret;pthread_t  tid[2];Linknode *head = create_linknode();if(argc < 2){fprintf(stderr,"Usage : %s filename\n",argv[0]);exit(EXIT_FAILURE);}if((fd = open(argv[1],O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0){fprintf(stderr,"fail to open %s,%s\n", argv[1],strerror(errno));exit(EXIT_FAILURE);}    ret = pthread_create(&tid[0],NULL,send_pthread,(void *)&fd);if(ret != 0){fprintf(stderr,"fail to pthread_create send_pthread,%s\n",strerror(errno));exit(EXIT_FAILURE);}ret = pthread_create(&tid[1],NULL,wake_thread,(void *)head);if(ret != 0){fprintf(stderr,"fail to pthread_create wake_thread ,%s\n",strerror(errno));exit(EXIT_FAILURE);}init_pthread_lock (&send_lock);init_pthread_lock(&wake_lock);init_pthread_cond(&send_cond);init_pthread_cond(&send_cond);while(1){printf("Input cmd>");scanf("%d",&cmd);insert_linknode(head,cmd);pthread_cond_signal(&wake_cond);if(cmd  == 4)break;}pthread_join(tid[0],NULL);pthread_join(tid[1],NULL);exit(EXIT_SUCCESS);}



原创粉丝点击