本文是我对锁以及线程的学习,虽然代码都是参考其他人的,但是我还是在他们代码的基础上根据自己的想法修改了一些的,大家在学的时候也记得要多改改来看运行结果,这样学的快。
生产者消费者学习:
参考链接 生产者消费者–c语言实现
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
pthread_mutex_t mtx; // 互斥锁,保证只有一个线程访问共享资源
pthread_cond_t cond_add; // 生产信号量
pthread_cond_t cond_del; // 消费信号量
int pool; // 资源池
int size; // 资源池上限
#define THREADS 3 // 开辟的线程数
pthread_t tid_pd[THREADS]; // 生产者线程组
pthread_t tid_cs[THREADS]; // 消费者线程组
void producer(void* id)
{
int threadid = *((int*)id);
printf("producer thread( id: %d ) started.\n", threadid);
while (1)
{
pthread_mutex_lock(&mtx);
while (pool >= size) // 我是一直让它while了,直到通知已经生产了一个资源时才继续
{
pthread_cond_wait(&cond_del, &mtx);
}
++pool;
printf("p%d add a good, pool is %d.\n", threadid, pool);
pthread_cond_signal(&cond_add);
pthread_mutex_unlock(&mtx);
}
return;
}
void consumer(void* id)
{
int threadid = *((int*)id);
printf("consumer thread( id: %d ) started.\n", threadid);
while (1)
{
pthread_mutex_lock(&mtx);
while (pool <= 0)
{
pthread_cond_wait(&cond_add, &mtx);
}
--pool;
printf("\t\t\t c%d del a good, pool is %d.\n", threadid, pool);
pthread_cond_signal(&cond_del);
pthread_mutex_unlock(&mtx);
}
return;
}
int main(int argc, char const* argv[])
{
// 给对于的锁及信号量开辟资源并初始化
pthread_mutex_init(&mtx, NULL);
pthread_cond_init(&cond_add, NULL);
pthread_cond_init(&cond_del, NULL);
pool = 0;
size = 10;
int i = 0;
// 创建生产者、消费者的线程
for (i = 0; i < THREADS; i++)
{
if (pthread_create(&tid_pd[i], NULL, (void*)producer, (void*)(&i)) != 0)
{
printf("create producer thread %d error!\n", i);
return 0;
}
usleep(100000); // 让线程能有足够时间起来
}
for (i = 0; i < THREADS; i++)
{
if (pthread_create(&tid_cs[i], NULL, (void*)consumer, (void*)(&i)) != 0)
{
printf("create consumer thread %d error!\n", i);
return 0;
}
usleep(100000);
}
// 依次对生产者、消费者线程进行退出
for (i = 0; i < THREADS; i++)
{
if (pthread_join(tid_pd[i], NULL) != 0)
{
printf("join producer thread %d error!\n", i);
return 0;
}
}
for (i = 0; i < THREADS; i++)
{
if (pthread_join(tid_cs[i], NULL) != 0)
{
printf("join consumer thread %d error!\n", i);
return 0;
}
}
// 销毁开辟的锁及信号量的空间
pthread_mutex_destroy(&mtx);
pthread_cond_destroy(&cond_add);
pthread_cond_destroy(&cond_del);
return 0;
}
哲学家就餐:
参考链接 哲学家就餐问题(C语言实现)
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<errno.h>
#include<unistd.h>
#define MAX_PHILOSOPHER_NUM 5
const char Philosopher[MAX_PHILOSOPHER_NUM + 1] = "ABCDE";
pthread_mutex_t chopstick[MAX_PHILOSOPHER_NUM + 1];
void* eat_think(void* arg)
{
int left, right; // 左右筷子的编号
char phiName = *((char*)arg);
switch (phiName) {
case 'A':
left = 5, right = 1;
break;
case 'B':
left = 1, right = 2;
break;
case 'C':
left = 2, right = 3;
break;
case 'D':
left = 3, right = 4;
break;
case 'E':
left = 4, right = 5;
break;
}
while (1)
{
usleep(3); //思考
pthread_mutex_lock(&chopstick[left]); // 拿起左手的筷子
printf("Philosopher %c fetches chopstick %d\n", phiName, left);
if (pthread_mutex_trylock(&chopstick[right]) != 0) // 拿起右手的筷子
{
pthread_mutex_unlock(&chopstick[left]); //如果右边筷子被拿走放下左手的筷子
continue;
}
//pthread_mutex_lock(&chopstick[right]); //拿起右手的筷子,如果想观察死锁,把上一句if注释掉,再把这一句的注释去掉
printf("Philosopher %c fetches chopstick %d\n", phiName, right);
printf("Philosopher %c is eating.\n", phiName);
usleep(3); //吃饭
pthread_mutex_unlock(&chopstick[left]); //放下左手的筷子
printf("Philosopher %c release chopstick %d\n", phiName, left);
pthread_mutex_unlock(&chopstick[right]); //放下右手的筷子
printf("Philosopher %c release chopstick %d\n", phiName, right);
}
}
int main()
{
int i;
pthread_t Philosopher_t[MAX_PHILOSOPHER_NUM]; // 哲学家
for (i = 0; i < MAX_PHILOSOPHER_NUM; ++i)
{
pthread_mutex_init(&chopstick[i], NULL);
pthread_create(&Philosopher_t[i], NULL, eat_think, (void*)(&Philosopher[i]));
}
for (i = 0; i < MAX_PHILOSOPHER_NUM; ++i)
{
pthread_join(Philosopher_t[i], NULL);
}
return 0;
}