# 代码介绍

- 用于创建互斥（mutex）变量
- 用于对互斥加锁，防止其他进程（线程）进入临界区。
- 用于创建临界区
- 标识线程

`

2. include <semaphore.h>

- sem_t
- 用于创建信号量变量
- sem_init
- 信号量初始化函数
- sem_wait
- 相当于Dijkstra的down操作
- sem_post
- 相当于Dijkstra的up操作

# 哲学家进餐问题

## 代码

#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>

#define N 5
#define LEFT (i - 1 + N) % N
#define RIGHT (i + 1) % N
#define THINKING 0
#define HUNGRY 1
#define EATING 2

int state[N];

sem_t s[N];

void think(int i)
{
if (state[i] == THINKING)
{
printf("philosopher %d is thinking.......\n", i);
sleep(3);
}
}

void eat(int i)
{
if (state[i] == EATING)
{
printf("philosopher %d is eating.......\n", i);
sleep(3);
}
}

void init()
{
int i;
for (i = 0; i < N; i++)
{
if (sem_init(&s[i], 1, 1) != 0)
{
printf("sem_init is wrong\n");
}
}
}

void test(int i)
{
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING)
{
state[i] = EATING;
sem_post(&s[i]);
return;
}
}
void take_forks(int i)
{
state[i] = HUNGRY;
test(i);
sem_wait(&s[i]);
}

void put_forks(int i)
{
state[i] = THINKING;
test(LEFT);
test(RIGHT);
}

void philosopher(int i)
{
while (1)
{
think(i);
take_forks(i);
eat(i);
put_forks(i);
}
}

int main()
{
int i = 0;

int ret;
init();

for (i = 0; i < N; i++)
{
ret = pthread_create(&id, NULL, (void *)philosopher, i);
if (ret != 0)
{
return 1;
}
}
}

# 读者-写者问题

## 代码实现

#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>

#define N 5

sem_t db; /* control the access of database  */
int rc;   /* the process want to access the database */

void init()
{
rc = 0;
if (sem_init(&db, 1, 1) != 0)
{
printf("sem_init is wrong\n");
}
}

{
sleep(3);
}

{
}

void write_data()
{
printf("person is writing.......\n");
sleep(5);
}

void finish_write()
{
printf("person finish writing!\n");
}

{
while (1)
{
rc += 1;
if (rc == 1)
sem_wait(&db);

rc -= 1;
if (rc == 0)
sem_post(&db);
sleep(3); /* wait for another reading ... */
}
}

void writer()
{
while (1)
{
sem_wait(&db);
write_data();
finish_write();
sem_post(&db); /* restore the access */
sleep(5);      /* wait for another writing ... */
}
}

int main()
{
int i = 0;

int ret1, ret2;
init();

for (i = 0; i < N; i++)
{
ret2 = pthread_create(&id2, NULL, (void *)writer, NULL);
if (ret1 != 0 || ret2 != 0)
{
return 1;
}
}
return 1;
}

1. 读者优先模式
2. 写者优先模式
3. 严格按照时间戳读写

# 参考资料

1. Operating System:Design and Implementation,Third Edition
2. 多线程同步--信号量
3. sen_init
4. Linux进程间通信——使用信号量
5. 哲学家进餐问题的C语言实现