免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 748 | 回复: 0
打印 上一主题 下一主题

linux 条件变量 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-07 13:39 |只看该作者 |倒序浏览
内涵:和一个普通互斥体结合使用的一块资源。包括了变量本身、正在等待的线程信息等。
初始化: pthread_cond_t cond = PTHREAD_COND_ININTIALIZER;
销毁:   pthread_cond_destroy(pthread_cond_t*);
等待和发送信号:
       假设:有一个房间,钥匙是mutex,一开始门是开着的。 房间内有一个电话cond,包括所有在上面已经登记过的电话号码(线程id)
       1. pthread_mutex_lock(&mutex);
       2. pthread_cond_wait(&cond, &mutex);
       // do sth
       3. pthread_mutex_unlock(&mutex);
       过程: 第1步,来了一个人小张(线程),先进房间并且锁上门,不让其他人同时进来。第2步,小张把自己的电话号码登记在了电话上。然后小张就打开锁出来了并且倒地就睡一直等到有人打电话给他,因为他要等其他人做完了一些事情之后打电话通知他以便它继续做。第3步,有人打电话给小张了,小张又进入房间并且锁上门,干他自己分内的事情了。。。

      phtread_cond_signal(&cond);按照某些规则挑一个电话号码(比如优先级高低)通知那个人(线程)


下面是我写的一个 用条件变量实现join所有线程的例子


#include "../common.h"       //常用的unix头文件,自己写

#include "netdb.h"
#include "pthread.h"

struct client_info {
        int tid;
        int is_end;
};
struct client_info ci[20];

int ndone = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;

class  client_reply {
public:
        int tid;
        char* msg;
};


void* client_work(void* arg) {
        printf("thread %d start...\n", pthread_self());
        int sockfd  = *((int*)arg);
        char buf[1024];
        for(;;) {
                int n  = read(sockfd, buf, sizeof(buf));
                if(n == 0)break;
                if(n == -1)break;
                buf[n] = 0;
                printf("thread %d read %d bytes:%s\n", pthread_self(), n, buf);
        }
        client_reply* p = new client_reply;
        p->msg = "oh baby";
        p->tid = pthread_self();
        pthread_mutex_lock(&mutex);
        ndone++;
        int i;
        for(i=0; itid, reply->msg);
                                memset(&ci, 0, sizeof(struct client_info));
                        }
                }
                pthread_mutex_unlock(&mutex);
        }
        return 0;
}

int main(int argc, char** argv) {


        memset(ci, 0, sizeof(struct client_info)*20);

        char* ip = NULL;
        char* port = "8888";

        if(argc > 1)ip = argv[1];
        if(argc > 2)port = argv[2];

        struct addrinfo *res;
        struct addrinfo hints;

        memset(&hints, 0, sizeof(hints));
        hints.ai_flags = AI_PASSIVE;
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;

        int n = getaddrinfo(ip, port, &hints, &res);
        if(n != 0)perror("getaddrinfo error");

        int sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if(sockfd == -1)perror("socket error");

        n = bind(sockfd, res->ai_addr, res->ai_addrlen);
        if(n == -1)perror("bind error");

        n = listen(sockfd, 5);
        if(n == -1)perror("listen error");

        char buf[1024];
        inet_ntop(AF_INET, &(((struct sockaddr_in*)res->ai_addr)->sin_addr), buf, sizeof(buf));

        printf("serer is started in [%s]:[%d]\n", buf, ntohs(((struct sockaddr_in*)res->ai_addr)->sin_port));


        //create a thread to recive client trhead
        pthread_t tid;
        pthread_create(&tid, 0, client_wait, 0);

        for(;;) {
                struct sockaddr_in client_addr;
                socklen_t client_addr_len = sizeof(client_addr);
                int clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_addr_len);
                if(clientfd == -1) {
                        perror("accept error");
                        continue;
                }
                pthread_t tid;
                int n = pthread_create(&tid, 0, client_work, &clientfd);
                if(n != 0)printf("pthread_create error\n");

        }
        return 0;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/62281/showart_679935.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP