互斥同步机制,互斥锁,无名信号量(信号灯),条件变量相关练习题

1.要求用信号量的方式实现,打印一次倒置一次。不允许使用flag.
提示:用多个信号量

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <semaphore.h>

// 1.定义无名信号量
sem_t sem1, sem2;
char buf[] = "1234567";

// 正常打印
void *task1(void *arg)
{
    // 1.p操作
    sem_wait(&sem1);
    printf("%s\n", buf);
    // 2.v操作
    sem_post(&sem2);
}

// 逆置打印
void *task2(void *arg)
{
    // 1.p操作
    sem_wait(&sem2);
    for (int i = strlen(buf); i >= 0; i--)
    {
        printf("%c", buf[i]);
    }
    printf("\n");
    // 2.v操作
    sem_post(&sem1);
}

int main(int argc, const char *argv[])
{
    pthread_t tid1, tid2, tid3;

    // 2.初始化无名信号量
    sem_init(&sem1, 0, 1);
    sem_init(&sem2, 0, 0);

    if ((errno = pthread_create(&tid1, NULL, task1, NULL)) != 0)
        printf("create thread1 error");
    if ((errno = pthread_create(&tid2, NULL, task2, NULL)) != 0)
        printf("create thread1 error");

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    // 3.销毁无名信号量
    sem_destroy(&sem1);
    sem_destroy(&sem2);

    return 0;
}

输出结果为:

2.将一个文件中的数据打印到终端,类似cat—一个文件,要求如下:
a.一个线程读取文件中的数据
b.另外—个线程打印文件中的数据

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// 1、定义条件变量,和互斥锁
pthread_cond_t cond;
pthread_mutex_t mutex;
int flag = 0;
int fd_r;
off_t size;
char buf[1000];
// 前半部分线程
void *task1(void *arg)
{
    // 获取互斥锁
    pthread_mutex_lock(&mutex);
    while (flag != 0)
        // 3、获取条件变量(里面包含了1将当前线程放在队列中;2解锁;
        // 3在队列中休眠;4重新获取锁;5从队列中移除;)
        pthread_cond_wait(&cond, &mutex);
    lseek(fd_r, 0, SEEK_SET);
        ssize_t r = read(fd_r, buf,size);
        if (r < 0)
        {
            perror("read");
            return NULL;
        }
       // fprintf(stderr,"%c",buf);
    
    printf("读取完成\n");
    flag = 1;
    // 释放条件变量:释放一个资源
    pthread_cond_signal(&cond);
    // 解锁
    pthread_mutex_unlock(&mutex);
}

// 后半部分线程
void *task2(void *arg)
{
    // 获取互斥锁
    pthread_mutex_lock(&mutex);
    while (0 == flag)
        // 3、获取条件变量(里面包含了1将当前线程放在队列中;2解锁;
        // 3在队列中休眠;4重新获取锁;5从队列中移除;)
    pthread_cond_wait(&cond, &mutex);
    //lseek(fd_r, size / 2, SEEK_SET);
    for (int i = 0; i < size; i++)
    {
        fprintf(stderr,"%c",buf[i]);
    }
    printf("打印完成\n");
    // sleep(1);
    flag = 0;
    // 释放条件变量:释放一个资源
    pthread_cond_signal(&cond);
    // 解锁
    pthread_mutex_unlock(&mutex);
}
int main(int argc, const char *argv[])
{
    fd_r = open(argv[1], O_RDONLY);
    if (fd_r < 0)
        perror("open");
    size = lseek(fd_r, 0, SEEK_END);
    pthread_t tid1, tid2; // 定义两个线程
    // 2、初始化条件变量和互斥锁
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    // 创建两个线程,并且判断是否创建成功
    if ((pthread_create(&tid1, NULL, task1, NULL)) != 0)
        printf("create thread1 error");
    if ((pthread_create(&tid2, NULL, task2, NULL)) != 0)
        printf("create thread1 error");
    

    pthread_join(tid1, NULL);      // 回收线程资源
    pthread_join(tid2, NULL);      // 回收线程资源
    pthread_mutex_destroy(&mutex); // 销毁锁
    pthread_cond_destroy(&cond);   // 销毁条件变量
    close(fd_r);//关闭条件描述符

    return 0;
}

输出结果:


3.现有ID号为a b c的三个线程,每个线程的任务都是循环打印自己id号,要求打印的顺序为abc

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<errno.h>
#include <semaphore.h>

// 1.定义无名信号量
sem_t sem1, sem2,sem3;

//打印A线程
void* task1(void* arg)
{
    while (1) {
        // 1.p操作
        sem_wait(&sem1);
        printf("A");
        // 2.v操作
        sem_post(&sem2);
    }
}

//打印B线程
void* task2(void* arg)
{
    while (1) {
        // 1.p操作
        sem_wait(&sem2);
        printf("B");
        // 2.v操作
        sem_post(&sem3);
    }
}
//打印C线程
void* task3(void* arg)
{
    while (1) {
        // 1.p操作
        sem_wait(&sem3);
        printf("C\n");
        // 2.v操作
        sem_post(&sem1);
    }
}
int main(int argc, const char* argv[])
{
    pthread_t tid1, tid2,tid3;

    // 2.初始化无名信号量
    sem_init(&sem1, 0, 1);
    sem_init(&sem2, 0, 0);
    sem_init(&sem3, 0, 0);

    if ((errno = pthread_create(&tid1, NULL, task1, NULL)) != 0)
        printf("create thread1 error");
    if ((errno = pthread_create(&tid2, NULL, task2, NULL)) != 0)
        printf("create thread1 error");
    if ((errno = pthread_create(&tid3, NULL, task3, NULL)) != 0)
        printf("create thread1 error");

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    pthread_join(tid3, NULL);

    // 3.销毁无名信号量
    sem_destroy(&sem1);
    sem_destroy(&sem2);
    sem_destroy(&sem3);

    return 0;
}

输出结果为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值