【Linux系统编程】【Google面试题改编】线程之间的同步与协调 Linux文件操作

2023-12-25 23:32:08

编写程序,有四个线程1、2、3、4

线程1的功能就是输1,线程2的功能就是输出2,以此类推……现在有四个文件ABCD初始都为空

现要让四个文件呈如下格式:

??? A: 1 22 333 4444 1 22 333 4444…

??? B: 22 333 4444 1 22 333 4444 1…

??? C: 333 4444 1 22 333 4444 1 22…

??? D: 4444 1 22 333 4444 1 22 333…

Linux C写的代码实现结果?

Linux C代码?

#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>

int counter = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
char*files[]={"A", "B", "C", "D"};
int orders[4]={0,3,2,1};
int fds[4];
void *new(void *vptr) {
    int*p=(int*)vptr;
    int times=*p;
    for (int i = 0; i < 32; i++) {
        pthread_mutex_lock(&mutex); // 加锁
        while (counter%4 != times-1)
            pthread_cond_wait(&cond, &mutex);
        counter++;
        char buffer[16];
        for(int j=0;j<times;j++)
            buffer[j]=times+'0';
        buffer[times]=' ';
        write(fds[orders[(4-times+1+i)%4]],buffer,times+1);
        if(i==31)
            write(fds[orders[(4-times+1+i)%4]],"\n",1);
        pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&mutex); // 解锁
    }
    return NULL;
}

int main(int argc, char **argv) {
    pthread_t threads[4];
    int times[4];
    for (int i = 0; i < 4; i++){
        times[i]=i+1;
        fds[i]=open(files[i],O_WRONLY|O_TRUNC);
        pthread_create(&threads[i], NULL, &new, &times[i]);
    }
    for (int i = 0; i < 4; i++)
        pthread_join(threads[i], NULL);
    pthread_mutex_destroy(&mutex); // 销毁互斥锁
    return 0;
}

?

首先创建四个空文件ABCD,要让四个线程协调工作需要用到互斥锁和条件变量,这里先声明初始化一下,并准备好四个文件的名字,orders等会解释用处,counter是用来计数区分四个线程的。

主函数创建了四个线程,需要让线程1打印一个1,线程2打印两个2,线程3打印3个3,线程4打印4个4,就需要向线程执行的函数传入一个参数来表示1234。这里使用了一个times数组而不是times整型变量,这是因为防止线程还没使用到正确的times值之前times又在下一次的循环中被修改了。打开四个文件准备写入,这里用的是只写和覆盖写。最后等待线程结束再退出。

在线程执行的函数中,先将指针转换为整型指针然后拿到整数的值,循环32次,这个循环次数无所谓,只是为了写多一点数据,每次循环中先加锁,然后判断counter和4取余是否等于打印*的次数减一,即判断是否轮到该线程输出,如果不是轮到该线程输出,那么该线程就进入等待,在某个线程输出完之后,counter++,同时唤醒所有等待线程并解锁。

然后接下来拼接出需要写入文件的字符串,然后最关键的地方来了,就是这个线程应该往哪个文件写这个字符串。

我们首先来观察一下我们需要达到的效果是怎么样的,首先得明白一个前提,即我们的线程是这样的:线程1打印一个1,线程2打印两个2,线程3打印3个3,线程4打印4个4。

那么线程1首先写文件A,完了写文件D,之后写文件C和文件D,从序数0开始计算的话,那么线程1写文件的顺序是这样的:0 3 2 1 0 3 2 1 0 3 2 1……

同时线程2写文件的顺序是这样的:1 0 3 2……,线程3写文件的顺序:2 1 0 3,线程4写文件的顺序:3 2 0 1,到这里就可以分析出来了,让一个数组int orders[4]={0,3,2,1},那么线程1写文件的顺序就是从第1个元素开始循环,而线程2写文件的顺序是从第4个元素开始循环,线程3写文件的顺序是从第3个元素开始循环,线程4写文件的顺序是从第2个元素开始循环,由此我们可以设计出代码实现。

编译运行程序,可见程序设计正确,成功按要求写入四个文件。

?怀疑我合起来输出造假,我再分开输出,合起来输出是为了好看和验证结果正确性。

文章来源:https://blog.csdn.net/weixin_62264287/article/details/135210530
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。