Last active
April 13, 2023 01:54
-
-
Save larryhou/07a1cb57a6e561d32a433bc2db6329d9 to your computer and use it in GitHub Desktop.
pthread_cond_wait sample https://blog.csdn.net/hairetz/article/details/4535920
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.c | |
// pthread_cond_wait | |
// | |
// Created by larryhou on 2023/4/12. | |
// | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; | |
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | |
struct object | |
{ | |
int id; | |
} *data = NULL; | |
static void cleanup(void *arg) | |
{ | |
printf("cleanup from thread 2\n"); | |
free(arg); | |
(void)pthread_mutex_unlock(&mtx); | |
} | |
static void *consume(void *arg) | |
{ | |
int *p = NULL; | |
pthread_cleanup_push(cleanup, p); | |
while (1) | |
{ | |
pthread_mutex_lock(&mtx); // 这个mutex主要是用来保证pthread_cond_wait的并发性 | |
while (data == NULL) | |
{ // 这个while要特别说明一下,单个pthread_cond_wait功能很完善,为何这里要有一个while (head == NULL)呢?因为pthread_cond_wait里的线程可能会被意外唤醒,如果这个时候head != NULL,则不是我们想要的情况。这个时候,应该让线程继续进入pthread_cond_wait | |
pthread_cond_wait(&cond, &mtx); // pthread_cond_wait会先解除之前的pthread_mutex_lock锁定的mtx,然后阻塞在等待对列里休眠,直到再次被唤醒(大多数情况下是等待的条件成立而被唤醒,唤醒后,该进程会先锁定先pthread_mutex_lock(&mtx);,再读取资源 | |
// 用这个流程是比较清楚的/*block-->unlock-->wait() return-->lock*/ | |
} | |
printf("read %d\n", data->id); | |
free(data); | |
data = NULL; | |
pthread_mutex_unlock(&mtx); // 临界区数据操作完毕,释放互斥锁 | |
} | |
pthread_cleanup_pop(0); | |
return 0; | |
} | |
int main(void) | |
{ | |
pthread_t tid; | |
pthread_create(&tid, NULL, consume, NULL); // 子线程会一直等待资源,类似生产者和消费者,但是这里的消费者可以是多个消费者,而不仅仅支持普通的单个消费者,这个模型虽然简单,但是很强大 | |
int i; | |
struct object *p; | |
for (i = 0; i < 10; i++) | |
{ | |
p = malloc(sizeof(struct object)); | |
p->id = i; | |
pthread_mutex_lock(&mtx); // 需要操作head这个临界资源,先加锁, | |
data = p; | |
pthread_cond_signal(&cond); | |
pthread_mutex_unlock(&mtx); // 解锁 | |
sleep(1); // wait for reading | |
} | |
printf("kill thread 2 from main thread\n"); | |
pthread_cancel(tid); // 关于pthread_cancel,有一点额外的说明,它是从外部终止子线程,子线程会在最近的取消点,退出线程,而在我们的代码里,最近的取消点肯定就是pthread_cond_wait()了。关于取消点的信息,有兴趣可以google,这里不多说了 | |
pthread_join(tid, NULL); | |
printf("complete\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment