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

先来个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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值