Boost库,linux pthread库的线程互斥锁和条件变量

来源:互联网 发布:js时间选择插件 编辑:程序博客网 时间:2024/05/01 04:00
先来个Boost库的例子,主线程为生产者,提供输入,子线程一作为消费者发送消息。#include <boost/format.hpp>#include <boost/thread/mutex.hpp>#include <boost/thread/condition.hpp>#include <boost/thread/thread.hpp>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <string>#include <iostream>boost::mutex mtx;boost::condition producer;boost::condition consumer;int MsgNum = 0;std::string SendBuf;void SendMsg(int fd);int main(int argc,char *argv[]){     int port = 8628;     std::string ip="192.168.18.22"     struct sockaddr_in ,d_addr;     memset(&d_addr,0,sizeof(d_addr));     d_addr.sin_family=AF_INET;     d_addr.sin_port=htons(port);     d_addr.sin_addr.s_addr=inet_addr(ip.c_str());     int sockfd=socket(PF_INET,SOCK_STREAM,0);     if(sockfd<0)          return 0;     if(connect(sockfd,(struct sockaddr *)&d_addr,sizeof(struct sockaddr))<0)     {          printf("connect error\n");          return 0;     }          MsgNum = 0;     boost::thread trd2(boost::bind(&SendMsg, sockfd)); //起子线程发送消息          while(1)     {          boost::mutex::scoped_lock sl(mtx); //占用互斥锁,未占用则阻塞           while(MsgNum>=1)          {               producer.wait(mtx);//如果存在未发送的消息,放开互斥锁并阻塞          }          printf("input string\n");          std::cin>>SendBuf;          MsgNum++;          consumer.notify_one();//通知消费者的条件变量结束wait     }}void SendMsg(int fd){     while(1)     {          boost::mutex::scoped_lock sl(mtx);  //占用互斥锁           while(MsgNum<=0)          {               consumer.wait(mtx); //初始化时MsgNum为0,放开互斥锁并阻塞          }          int n=send(fd, SendBuf.c_str() ,SendBuf.size(),0);          if(n<=0)          {               std::cout<<"send error"<<std::endl;               break;          }          else               std::cout<<"send success"<<std::endl;          MsgNum--;          producer.notify_one();//通知条件变量     }}


再来个pthread库的例子。#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <unistd.h>#include <pthread.h>#include <errno.h>static pthread_cond_t cond;static pthread_mutex_t mtx;struct node {        int n_number;        struct node *n_next;} *head = NULL;/*[thread_func]*/static void cleanup_handler(void *arg){        printf("Cleanup handler of second thread\n");        free(arg);        (void)pthread_mutex_unlock(&mtx);}static void *thread_func(void *arg) {         struct node *p = NULL;         pthread_cleanup_push(cleanup_handler, p);//当线程被取消或者pthread_cleanup_pop被调用且参数非零时,调用压栈的清理函数        while (1)        {                 pthread_mutex_lock(&mtx);           //这个mutex主要是用来保证pthread_cond_wait的并发性                 while (head == NULL)                  {                                                         pthread_cond_wait(&cond, &mtx);  // pthread_cond_wait会先解锁mtx,然后阻塞,直到再次被唤醒。唤醒后,该进程会先pthread_mutex_lock(&mtx);,再读取资源                }                 p = head;                 head = head->n_next;                 printf("Got %d from front of queue\n", p->n_number);                 free(p);                 pthread_mutex_unlock(&mtx);             //临界区数据操作完毕,释放互斥锁         }         pthread_cleanup_pop(0);         return 0; } int main(void) {     pthread_t tid;     int i;     struct node *p;     pthread_create(&tid, NULL, thread_func, NULL);   //子线程会一直等待资源,类似生产者和消费者,但是这里的消费者可以是多个消费者,而不仅仅支持普通的单个消费者,这个模型虽然简单,但是很强大     /*[tx6-main]*/     for (i = 0; i < 10; i++) {         p = malloc(sizeof(struct node));         p->n_number = i;         pthread_mutex_lock(&mtx);             //需要操作head这个临界资源,先加锁,         p->n_next = head;         head = p;         pthread_cond_signal(&cond);         pthread_mutex_unlock(&mtx);           //解锁         sleep(1);  //注意,这个sleep必不可少,否则输出逆序。原因:pthread_cond_signal本身只发送通知信号而不是解锁,发送完信号就返回。这一秒的时间是让线程完成工作后再次wait的。    }     printf("thread 1 wanna end the line.So cancel thread 2./n");     pthread_cancel(tid);             //关于pthread_cancel,有一点额外的说明,它是从外部终止子线程,子线程会在最近的取消点,退出线程,而在我们的代码里,最近的取消点肯定就是pthread_cond_wait()了。关于取消点的信息,有兴趣可以google,这里不多说了     pthread_join(tid, NULL);     printf("All done -- exiting/n");     return 0; }



0 0
原创粉丝点击