前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux系统编程】【Google面试题改编】线程之间的同步与协调 Linux文件操作

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

作者头像
叶茂林
发布2023-12-26 09:51:06
1920
发布2023-12-26 09:51:06
举报

编写程序,有四个线程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代码 

代码语言:javascript
复制
#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个元素开始循环,由此我们可以设计出代码实现。

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档