名词解释
名称 | 备注 |
---|---|
Posix(Portable Operating System Interface of UNIX) | 可移植操作系统接口 |
System V | Unix操作系统的一个版本 |
pipe | 管道 |
named pipe | 有名管道 |
mutex(mutual exclusion) | 互斥锁 |
condtion variable | 条件变量 |
read-write lock | 读写锁 |
record locking | 记录上锁 |
message queue | 消息队列 |
semaphore | 信号量 |
shared memory | 共享内存区 |
分类 | IPC |
---|---|
Pipe | 管道 |
有名管道 | |
Synchronization | Posix互斥锁 |
Posix条件变量 | |
Posix读写锁 | |
fcntl记录上锁 | |
Posix IPC | Posix消息队列 |
Posix信号量 | |
Posix共享内存区 | |
System V IPC | System V消息队列 |
System V信号量 | |
System V共享内存区 |
互斥锁和条件变量
互斥锁用于上锁,条件变量用于等待
pthread_cond_wait函数原子地执行以下两个动作:
- 1、给互斥锁解锁
- 2、把调用线程投入睡眠,直到被另一个线程调用pthread_cond_signal函数唤醒
#include "stdio.h"
#include "stdlib.h"
#include "pthread.h"
#define MAXNITEMS 1000000
#define MAXNTHREADS 100
int nitems, buff[MAXNITEMS], nsignals;
struct {
pthread_mutex_t mutex;
int nput, nval;
} put = {PTHREAD_MUTEX_INITIALIZER};
struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
int nready;
} nready = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
int min(int a, int b) {
return a < b? a: b;
}
void *produce(void *arg) {
int dosignal;
for (;;) {
pthread_mutex_lock(&put.mutex);
if (put.nput >= nitems) {
pthread_mutex_unlock(&put.mutex);
return 0;
}
buff[put.nput] = put.nval;
put.nput++;
put.nval++;
pthread_mutex_unlock(&put.mutex);
dosignal = 0;
pthread_mutex_lock(&nready.mutex);
if (nready.nready == 0) {
dosignal = 1;
}
nready.nready++;
pthread_mutex_unlock(&nready.mutex);
if (dosignal) {
pthread_cond_signal(&nready.cond);
nsignals++;
}
(*((int *)arg))++;
}
return 0;
}
void *consume(void *arg) {
int i;
for (i = 0; i < nitems; ++i) {
pthread_mutex_lock(&nready.mutex);
while (nready.nready == 0) {
pthread_cond_wait(&nready.cond, &nready.mutex);
}
nready.nready--;
pthread_mutex_unlock(&nready.mutex);
if (buff[i] != i) {
printf("buff[%d] = %d\n", i, buff[i]);
}
}
return 0;
}
int main(int argc, char **argv) {
int i, nthreads, count[MAXNTHREADS];
pthread_t tid_produce[MAXNTHREADS], tid_consume;
if (argc != 3) {
printf("usage: prodcons7 <#items> <#threads>");
exit(1);
}
nitems = min(atoi(argv[1]), MAXNITEMS);
nthreads = min(atoi(argv[2]), MAXNTHREADS);
pthread_setconcurrency(nthreads + 1);
for (i = 0; i < nthreads; ++i) {
count[i] = 0;
pthread_create(&tid_produce[i], 0, produce, &count[i]);
}
pthread_create(&tid_consume, 0, consume, 0);
for (i = 0; i < nthreads; ++i) {
pthread_join(tid_produce[i], 0);
printf("count[%d] = %d\n", i, count[i]);
}
pthread_join(tid_consume, 0);
printf("nsignals = %d\n", nsignals);
exit(0);
}