互斥锁和条件变量 能用于 线程同步
如果 互斥锁 和 条件变量 存放在 共享内存中,还能 实现 进程同步
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 静态分配互斥锁
static pthread_mutex_t lock = PTHREAD_MUTEX_INITALIZER;
// 动态分配
pthread_mutex_t *lock2 = malloc(sizeof(*lock2));
phread_mutex_init()
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
若资源已经被上锁,
锁数据,不是函数
生产者消费者问题
使用共享内存之类需要显示同步的情况
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAXNITEMS 0x0fffffff
#define MAXNTHREADS 100
int nitems;
struct {
pthread_mutex_t mutex;
int buf[MAXNITEMS];
int nput;
int nval;
} shared = {
.mutex = PTHREAD_MUTEX_INITIALIZER
};
void *produce(void *arg);
void *consume(void *arg);
int main(int argc, char *argv[])
{
int i, nthreads, count[MAXNTHREADS];
pthread_t tid_produce[MAXNTHREADS], tid_consume;
if (argc != 3) {
printf("usage : %s <items> <threads>\n", argv[0]);
return -1;
}
nitems = atoi(argv[1]) > MAXNITEMS ? MAXNITEMS : atoi(argv[1]);
nthreads = atoi(argv[2]) > MAXNTHREADS ? MAXNTHREADS : atoi(argv[2]);
for (i = 0; i < nthreads; i++) {
count[i] = 0; // 给每个线程一个计数器,记录线程 对共享内存区域操作了多少次
pthread_create(&tid_produce[i], NULL, produce, &count[i]);
}
for (i = 0; i < nthreads; i++) {
pthread_join(tid_produce[i], NULL);
printf("count[%d] = %d\n", i, count[i]);
}
pthread_create(&tid_consume, NULL, consume, NULL);
pthread_join(tid_consume, NULL);
return 0;
}
void *produce(void *arg)
{
for (;;) {
pthread_mutex_lock(&shared.mutex);
if (shared.nput >= nitems) { // 所有的区域都写完了,退出
pthread_mutex_unlock(&shared.mutex);
return NULL;
}
shared.buf[shared.nput] = shared.nval;
shared.nput++; // nput 和 nval 增量都是 1,且初始值都是 0, 所以没有冲突情况下 shared.buf[i] == i
shared.nval++;
pthread_mutex_unlock(&shared.mutex);
*(int *)arg += 1; // 增加线程操作计数
}
}
void *consume(void *arg)
{
int i;
for (i = 0; i < nitems; ++i) {
if (shared.buf[i] != i) { // 若出现冲突,则输出
printf("buf[%d] != %d\n", i, shared.buf[i]);
}
}
return NULL;
}
加锁输出
[root@VM-0-12-centos test]# ./a.out 1000000000 5
count[0] = 54572343
count[1] = 53444696
count[2] = 47935356
count[3] = 56164561
count[4] = 56318499
不加锁
[root@localhost test]# ./a.out 10000 4
count[0] = 8596
count[1] = 8192
count[2] = 0
count[3] = 0
buf[8978] != 8977
buf[9152] != 9151
对代码进行修改,让消费者和生产者一起工作
void consume_wait(int i)
{
for (;;) {
pthread_mutex_lock(&shared.mutex);
if (i < shared.nput) {
pthread_mutex_unlock(&shared.mutex);
return;
}
pthread_mutex_unlock(&shared.mutex);
}
}
void *consume(void *arg)
{
int i;
for (i = 0; i < nitems; ++i) {
consume_wait(i); // 消费 下标为 i 的元素前,检查是否被生产
if (shared.buf[i] != i) { // 若出现冲突,则输出
printf("buf[%d] != %d\n", i, shared.buf[i]);
}
}
return NULL;
}
生产者使用轮询的方式检查条件,浪费cpu,所以希望 能阻塞 直到 条件满足。
这需要条件变量。
原文:https://www.cnblogs.com/yangxinrui/p/15221354.html