练习1
请使用互斥锁 和 信号量分别实现5个线程之间的同步
互斥锁实现同步
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
//创建互斥锁
pthread_mutex_t m;
pthread_mutex_t m1;
pthread_mutex_t m2;
pthread_mutex_t m3;
pthread_mutex_t m4;
void* thread_main1(void* arg)
{
while(1)
{
pthread_mutex_lock(&m1);
printf("1#线程\n");
sleep(1);
pthread_mutex_unlock(&m2);
}
}
void* thread_main2(void* arg)
{
while(1)
{
pthread_mutex_lock(&m2);
printf("2#线程\n");
sleep(1);
pthread_mutex_unlock(&m3);
}
}
void* thread_main3(void* arg)
{
while(1)
{
pthread_mutex_lock(&m3);
printf("3#线程\n");
sleep(1);
pthread_mutex_unlock(&m4);
}
}
void* thread_main4(void* arg)
{
while(1)
{
pthread_mutex_lock(&m4);
printf("4#线程\n");
printf("-------------\n");
sleep(1);
pthread_mutex_unlock(&m);
}
}
int main(int argc, const char *argv[])
{
//初始化互斥锁
pthread_mutex_init(&m,NULL);
pthread_mutex_init(&m1,NULL);
pthread_mutex_init(&m2,NULL);
pthread_mutex_init(&m3,NULL);
pthread_mutex_init(&m4,NULL);
pthread_mutex_lock(&m1);
pthread_mutex_lock(&m2);
pthread_mutex_lock(&m3);
pthread_mutex_lock(&m4);
//创建4个分支线程
pthread_t id1;
pthread_create(&id1,0,thread_main1,0);
pthread_detach(id1);
pthread_t id2;
pthread_create(&id2,0,thread_main2,0);
pthread_detach(id2);
pthread_t id3;
pthread_create(&id3,0,thread_main3,0);
pthread_detach(id3);
pthread_t id4;
pthread_create(&id4,0,thread_main4,0);
pthread_detach(id4);
//主线程
while(1)
{
pthread_mutex_lock(&m);
printf("主线程\n");
sleep(1);
pthread_mutex_unlock(&m1);
}
//销毁互斥锁
pthread_mutex_destroy(&m);
pthread_mutex_destroy(&m1);
pthread_mutex_destroy(&m2);
pthread_mutex_destroy(&m3);
pthread_mutex_destroy(&m4);
return 0;
}
信号量实现同步
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
//创建信号量
sem_t s;
sem_t s1;
sem_t s2;
sem_t s3;
sem_t s4;
void* thread_main1(void* arg)
{
while(1)
{
sem_wait(&s1);
printf("1#线程\n");
sleep(1);
sem_post(&s2);
}
}
void* thread_main2(void* arg)
{
while(1)
{
sem_wait(&s2);
printf("2#线程\n");
sleep(1);
sem_post(&s3);
}
}
void* thread_main3(void* arg)
{
while(1)
{
sem_wait(&s3);
printf("3#线程\n");
sleep(1);
sem_post(&s4);
}
}
void* thread_main4(void* arg)
{
while(1)
{
sem_wait(&s4);
printf("4#线程\n");
printf("----------------\n");
sleep(1);
sem_post(&s);
}
}
int main(int argc, const char *argv[])
{
//初始化信号量
sem_init(&s,0,1);
sem_init(&s1,0,1);
sem_init(&s2,0,1);
sem_init(&s3,0,1);
sem_init(&s4,0,1);
sem_wait(&s1);
sem_wait(&s2);
sem_wait(&s3);
sem_wait(&s4);
//创建4个分支线程
pthread_t id1;
pthread_create(&id1,0,thread_main1,0);
pthread_detach(id1);
pthread_t id2;
pthread_create(&id2,0,thread_main2,0);
pthread_detach(id2);
pthread_t id3;
pthread_create(&id3,0,thread_main3,0);
pthread_detach(id3);
pthread_t id4;
pthread_create(&id4,0,thread_main4,0);
pthread_detach(id4);
//销毁信号量
sem_destroy(&s);
sem_destroy(&s1);
sem_destroy(&s2);
sem_destroy(&s3);
sem_destroy(&s4);
//主线程
while(1)
{
sem_wait(&s);
printf("主线程\n");
sleep(1);
sem_post(&s1);
}
return 0;
}
练习2
请使用条件变量实现2生产者2消费者模型,注意1个生产者在生产的时候,另外一个生产者不能生产
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFFER_SIZE 5 // 缓冲区大小
#define NUM_PRODUCERS 2 // 生产者数量
#define NUM_CONSUMERS 2 // 消费者数量
// 环形缓冲区
int buffer[BUFFER_SIZE];
int in = 0; // 下一个生产者放入数据的位置
int out = 0; // 下一个消费者取出数据的位置
int count = 0; // 当前缓冲区的元素个数
pthread_mutex_t mutex; // 互斥锁
pthread_cond_t not_full; // 缓冲区不满时的条件变量
pthread_cond_t not_empty; // 缓冲区不空时的条件变量
pthread_cond_t producer_cond; // 控制生产者互斥的条件变量
void *producer(void *arg) {
int id = *((int *)arg);
while (1) {
sleep(rand() % 2); // 模拟生产时间
pthread_mutex_lock(&mutex);
// 确保每次只有一个生产者在生产
if (id == 1) {
pthread_cond_wait(&producer_cond, &mutex); // 如果是生产者2,等生产者1生产
}
// 等待缓冲区有空间
while (count == BUFFER_SIZE) {
pthread_cond_wait(¬_full, &mutex);
}
// 生产数据并放入缓冲区
buffer[in] = rand() % 100;
printf("Producer %d produced: %d\n", id, buffer[in]);
in = (in + 1) % BUFFER_SIZE;
count++;
// 通知消费者缓冲区有数据可以消费
pthread_cond_signal(¬_empty);
// 唤醒另一个生产者
if (id == 0) {
pthread_cond_signal(&producer_cond); // 唤醒生产者2
}
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void *consumer(void *arg) {
while (1) {
sleep(rand() % 3); // 模拟消费时间
pthread_mutex_lock(&mutex);
// 等待缓冲区有数据
while (count == 0) {
pthread_cond_wait(¬_empty, &mutex);
}
// 消费数据
int data = buffer[out];
printf("Consumer consumed: %d\n", data);
out = (out + 1) % BUFFER_SIZE;
count--;
// 通知生产者缓冲区有空间可以生产
pthread_cond_signal(¬_full);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
pthread_t producers[NUM_PRODUCERS], consumers[NUM_CONSUMERS];
int ids[NUM_PRODUCERS] = {0, 1}; // 生产者的 ID
// 初始化锁和条件变量
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(¬_full, NULL);
pthread_cond_init(¬_empty, NULL);
pthread_cond_init(&producer_cond, NULL);
// 创建生产者和消费者线程
for (int i = 0; i < NUM_PRODUCERS; i++) {
if (pthread_create(&producers[i], NULL, producer, (void *)&ids[i]) != 0) {
perror("Producer thread creation failed");
return 1;
}
}
for (int i = 0; i < NUM_CONSUMERS; i++) {
if (pthread_create(&consumers[i], NULL, consumer, NULL) != 0) {
perror("Consumer thread creation failed");
return 1;
}
}
// 设置生产者1为启动生产的线程
pthread_cond_signal(&producer_cond);
// 等待所有线程结束
for (int i = 0; i < NUM_PRODUCERS; i++) {
pthread_join(producers[i], NULL);
}
for (int i = 0; i < NUM_CONSUMERS; i++) {
pthread_join(consumers[i], NULL);
}
// 销毁锁和条件变量
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(¬_full);
pthread_cond_destroy(¬_empty);
pthread_cond_destroy(&producer_cond);
return 0;
}