beers.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
int beers = 2000000;
// 创建互斥锁,互斥锁对所有可能发生冲突的线程可见,是一个全局变量.
// PTHREAD_MUTEX_INITIALIZER实际上是一个宏,当编译器看到它,就会插入创建互斥锁的代码
pthread_mutex_t beers_lock = PTHREAD_MUTEX_INITIALIZER;
void* drink_lots_1(void* a) {
int i;
pthread_mutex_lock(&beers_lock); // 一次只有一个线程能通过这里
// 含有共享数据的代码从这里开始
for(i = 0; i < 100000; i++) {
beers -= 1;
}
// ...代码结束了
pthread_mutex_unlock(&beers_lock);
printf("beers = %i \n", beers);
return NULL;
}
// 另外一种上锁方式
void* drink_lots(void* a) {
int i;
for(i = 0; i < 100000; i++) {
pthread_mutex_lock(&beers_lock);
beers -= 1;
pthread_mutex_unlock(&beers_lock);
}
printf("beers = %i \n", beers);
return NULL;
}
void error(char *msg)
{
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(1); // 非正常运行导致退出程序,这是系统级别的
}
int main()
{
pthread_t threads[20];
int t;
printf("%i bottles of beer on the wall \n%i bottles of beer\n", beers, beers);
for(t = 0; t < 20; t++) {
if(pthread_create(&threads[t], NULL, drink_lots, NULL) == -1)
error("fail to create thread.");
}
void* result;
for(t = 0; t < 20; t++) {
// pthread_join() 函数会等待线程结束
if(pthread_join(threads[t], &result) == -1)
error("fail to recycle thread."); //无法回收线程
}
printf("There are now %i bottles of beer on the wall\n", beers);
return 0;
}
build:
gcc beers.c -lpthread -o beers