- 浏览: 208516 次
- 性别:
- 来自: 重庆
-
文章分类
最新评论
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
void* testThreadPool(int *t);
pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t clifd_cond = PTHREAD_COND_INITIALIZER;
int a = 0;
int main() {
int sock_fd, conn_fd;
int optval;
socklen_t cli_len;
struct sockaddr_in cli_addr, serv_addr;
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
printf("socket\n");
}
optval = 1;
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
sizeof(int)) < 0) {
printf("setsockopt\n");
}
memset(&serv_addr, 0, sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(4507);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock_fd, (struct sockaddr *) &serv_addr,
sizeof(struct sockaddr_in)) < 0) {
printf("bind\n");
}
if (listen(sock_fd, 100) < 0) {
printf("listen\n");
}
cli_len = sizeof(struct sockaddr_in);
int t;
pthread_t * mythread;
mythread = (pthread_t*) malloc(100 * sizeof(pthread_t));
for (t = 0; t < 5; t++) {
int *i=(int*)malloc(sizeof(int));
*i=t;
if (pthread_create(&mythread[t], NULL, (void*)testThreadPool, (void*)i) != 0) {
printf("pthread_create");
}
}
while (1) {
conn_fd = accept(sock_fd, (struct sockaddr *) &cli_addr, &cli_len);
if (conn_fd < 0) {
printf("accept\n");
}
printf("accept a new client, ip:%s\n", inet_ntoa(cli_addr.sin_addr));
pthread_mutex_lock(&clifd_mutex);
a=conn_fd;
pthread_cond_signal(&clifd_cond);
pthread_mutex_unlock(&clifd_mutex);
}
return 0;
}
void* testThreadPool(int *t) {
printf("t is %d\n", *t);
for (;;) {
pthread_mutex_lock(&clifd_mutex);
pthread_cond_wait(&clifd_cond, &clifd_mutex);
printf("a is %d\n", a);
printf("t is %d\n", *t);
pthread_mutex_unlock(&clifd_mutex);
sleep(100);
}
return (void*) 0;
}
了解 pthread_cond_wait() 的作用非常重要 -- 它是 POSIX 线程信号发送系统的核心,也是最难以理解的部分。
首先,让我们考虑以下情况:线程为查看已链接列表而锁定了互斥对象,然而该列表恰巧是空的。这一特定线程什么也干不了 -- 其设计意图是从列表中除去节点,但是现在却没有节点。因此,它只能:
锁定互斥对象时,线程将调用 pthread_cond_wait(&mycond,&mymutex)。pthread_cond_wait() 调用相当复杂,因此我们每次只执行它的一个操作。
pthread_cond_wait() 所做的第一件事就是同时对互斥对象解锁(于是其它线程可以修改已链接列表),并等待条件 mycond 发生(这样当 pthread_cond_wait() 接收到另一个线程的“信号”时,它将苏醒)。现在互斥对象已被解锁,其它线程可以访问和修改已链接列表,可能还会添加项。 【要求解锁并阻塞是一个原子操作】
此时,pthread_cond_wait() 调用还未返回。对互斥对象解锁会立即发生,但等待条件 mycond 通常是一个阻塞操作,这意味着线程将睡眠,在它苏醒之前不会消耗 CPU 周期。这正是我们期待发生的情况。线程将一直睡眠,直到特定条件发生,在这期间不会发生任何浪费 CPU 时间的繁忙查询。从线程的角度来看,它只是在等待 pthread_cond_wait() 调用返回。
现在继续说明,假设另一个线程(称作“2 号线程”)锁定了 mymutex 并对已链接列表添加了一项。在对互斥对象解锁之后,2 号线程会立即调用函数 pthread_cond_broadcast(&mycond)。此操作之后,2 号线程将使所有等待 mycond 条件变量的线程立即苏醒。这意味着第一个线程(仍处于 pthread_cond_wait() 调用中)现在将苏醒。
现在,看一下第一个线程发生了什么。您可能会认为在 2 号线程调用 pthread_cond_broadcast(&mymutex) 之后,1 号线程的 pthread_cond_wait() 会立即返回。不是那样!实际上,pthread_cond_wait() 将执行最后一个操作:重新锁定 mymutex。一旦 pthread_cond_wait() 锁定了互斥对象,那么它将返回并允许 1 号线程继续执行。那时,它可以马上检查列表,查看它所感兴趣的更改。
停止并回顾!
那个过程非常复杂,因此让我们先来回顾一下。第一个线程首先调用:
pthread_mutex_lock(&mymutex);
然后,它检查了列表。没有找到感兴趣的东西,于是它调用:
pthread_cond_wait(&mycond, &mymutex);
然后,pthread_cond_wait() 调用在返回前执行许多操作:
pthread_mutex_unlock(&mymutex);
它对 mymutex 解锁,然后进入睡眠状态,等待 mycond 以接收 POSIX 线程“信号”。一旦接收到“信号”(加引号是因为我们并不是在讨论传统的 UNIX 信号,而是来自 pthread_cond_signal() 或 pthread_cond_broadcast() 调用的信号),它就会苏醒。但 pthread_cond_wait() 没有立即返回 -- 它还要做一件事:重新锁定 mutex:
pthread_mutex_lock(&mymutex);
pthread_cond_wait() 知道我们在查找 mymutex “背后”的变化,因此它继续操作,为我们锁定互斥对象,然后才返回。
发表评论
-
线程属性pthread_attr_t简介
2013-01-05 10:57 3930本文编辑整理自: http://hi.baidu.c ... -
避免内存碎片
2012-12-13 10:49 1495许多书籍提到过内存碎片,也看到一些方法防治内存 ... -
Linux程序设计中由线程使用不当引起的内存泄漏
2012-12-13 10:27 1403Linux程序设计中,创建线程时调用pthread_ ... -
EPOLL ET 模式下事件触发的场景
2012-09-25 10:13 1880ET模式称为边缘触发模式,顾名思义,不到边缘情况,是死都 ... -
惊群问题的思考
2012-09-25 10:13 942“据说”惊群问题已经是一个很古老的问题了,并且在大多数系统中已 ... -
linux惊群问题之udp
2012-09-25 10:12 1608今天测试udp服务器进程时发现log中记录了 ... -
getaddrinfo()函数详解
2012-09-19 10:59 8811. 概述IPv4中使用gethostbyname()函数完成 ... -
Linux的mmap文件内存映射机制
2012-09-19 15:00 2348在讲述文件映 ... -
Berkeley DB 由浅入深【转自架构师杨建】
2012-09-19 15:00 1969在网上看到不少介绍Berkeley DB的文章,几乎 ... -
linux 多线程编程
2012-09-19 15:00 1522进程与线程 进程是程序执行时的一个实例 ... -
linux下创建守护进程(daemon process)代码
2012-09-18 13:47 1655#include <stdio.h> ... -
dup and dup2的剖析
2012-09-18 13:35 672dup和dup2都可用来复制一个现存的文件描述符,使两个 ... -
C语言系统资源控制(getrlimit && setrlimit)
2012-09-18 11:52 988每一个进程都有自己的一组资源限制,在(*)inux系统中 ... -
UNIX缓冲机制
2012-09-18 11:11 1011某日一朋友写了一个HELL ...
相关推荐
`pthread_cond_wait()` 是 POSIX 线程库中的一个关键函数,用于线程同步。它与互斥锁(mutex)一起工作,允许线程在特定条件满足时挂起执行,等待其他线程发出信号。在深入分析 `pthread_cond_wait()` 的用法之前,...
《深入理解pthread_cond_wait:多线程同步的关键》 在多线程编程中,线程间的同步至关重要,而`pthread_cond_wait`就是一种用于线程间同步的重要工具,它属于POSIX线程库(pthread)的一部分。这个函数使得一个线程...
在Linux多线程编程中,`pthread_cond_wait()`是一个关键的同步原语,它用于线程间的通信和协作。在使用`pthread_cond_wait()`时,通常会在调用它之前加入一个while循环来判断条件是否满足。这个做法是为了避免虚假...
### pthread_cond_wait详解 #### 一、pthread_cond_wait概述 `pthread_cond_wait` 是一个用于线程间同步的重要函数,通常配合互斥锁 `pthread_mutex_t` 使用,以实现线程间的条件等待与唤醒机制。当某个线程需要...
在这个主题中,我们将深入探讨如何使用互斥锁(mutex)和条件变量(pthread_cond_wait, pthread_cond_signal)来实现线程间的同步和通信,从而解决条件阻塞的问题。 1. **互斥锁(Mutex)** 互斥锁是一种同步机制...
通过调用`pthread_cond_wait()`函数,线程可以在等待条件变为真时释放对互斥锁的持有,进入睡眠状态。当其他线程改变了这个条件并调用`pthread_cond_signal()`或`pthread_cond_broadcast()`时,等待的线程会被唤醒,...
6. **线程间通信**:`pthread_cond_broadcast()`、`pthread_cond_signal()`和`pthread_cond_wait()`等函数用于线程间的通信,协调工作进度。 7. **线程局部存储**:`pthread_key_create()`和`pthread_getspecific()...
我只想要进程的某个线程休眠一段时间的,可是用sleep()是将整个进程都休眠的,这个可能达不到,我们想要的效果... 采用pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t *mutex, const struct timesp
5. `pthread_cond_t` 和 `pthread_cond_init() / pthread_cond_wait() / pthread_cond_signal() / pthread_cond_broadcast()`:条件变量,用于线程间通信和同步,当满足特定条件时,一个线程通知其他等待线程。...
create()`用于创建新的线程,`pthread_join()`用于等待线程结束,`pthread_mutex_t`和`pthread_mutex_lock()`、`pthread_mutex_unlock()`用于互斥锁,保证资源的安全访问,`pthread_cond_t`和`pthread_cond_wait()`...
常用函数有`pthread_cond_init()`、`pthread_cond_wait()`和`pthread_cond_signal()`。 3. 信号量:一种计数型同步机制,可以实现线程间的资源控制和同步。`sem_open()`、`sem_post()`和`sem_wait()`等函数用于信号...
- **条件变量**:允许线程等待某个特定条件满足后再继续执行,例如`pthread_cond_wait`和`pthread_cond_signal`。 - **读写锁**:允许多个线程同时读取共享数据,但只允许一个线程进行写操作,如`pthread_rwlock_...
4. **条件变量**:在使用 `pthread_cond_wait` 和 `pthread_cond_signal` 等条件变量函数时,也需要用到 `pthread_self` 来确定发送信号或等待的线程。 5. **线程退出**:有时,你需要知道哪个线程正在执行特定的...
线程可以使用`pthread_cond_wait`函数等待条件变量,并在条件满足时通过`pthread_cond_signal`或`pthread_cond_broadcast`唤醒等待的线程。条件变量常与互斥锁配合使用,防止信号发送时的数据不一致。 3. **信号量*...
- **条件变量**(Condition Variable):`pthread_cond_t`表示条件变量,`pthread_cond_init()`和`pthread_cond_destroy()`用于初始化和销毁,`pthread_cond_wait()`和`pthread_cond_signal()`或`pthread_cond_...
在分析提供的源代码时,我们可以看到如何使用`pthread_mutex_lock()`和`pthread_mutex_unlock()`来控制对缓冲区的访问,并可能使用`pthread_cond_wait()`和`pthread_cond_signal()`或`pthread_cond_broadcast()`来...
- **条件变量(Condition Variables)**:`pthread_cond_t`用于线程间的通信和同步,`pthread_cond_wait()`使线程等待,`pthread_cond_signal()`或`pthread_cond_broadcast()`唤醒等待的线程。 - **信号量...
- **pthread_cond_wait()/pthread_cond_signal()**:等待条件变量和通知其他线程。 ### pthread互斥锁(Mutex) #### 什么是Mutex? 互斥锁是一种同步原语,用于保护临界区,即一段只能由一个线程访问的代码或数据...
在Linux中,条件变量由`pthread_cond_t`表示,`pthread_cond_init`初始化,`pthread_cond_wait`等待,`pthread_cond_signal`或`pthread_cond_broadcast`唤醒等待的进程。 3. **共享内存**:共享内存是Linux IPC的一...