Go并发编程实践与竞态条件解析

1、编写一个Go程序,该程序接受一个文本文件名列表作为参数。对于每个文件名,程序应生成一个新的goroutine,将该文件的内容输出到控制台。在掌握更好的方法之前,可以使用time.Sleep()函数等待子goroutine完成。将该程序命名为catfiles.go。可以按以下方式执行此Go程序:go run catfiles.go txtfile1 txtfile2 txtfile3

以下是实现该功能的示例代码:

package main

import (
    "bufio"
    "fmt"
    "os"
    "time"
)

func printFileContents(filename string) {
    file, err := os.Open(filename)
    if err != nil {
        fmt.Printf("无法打开文件 %s: %v\n", filename, err)
        return
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }

    if err := scanner.Err(); err != nil {
        fmt.Printf("读取文件 %s 时出错: %v\n", filename, err)
    }
}

func main() {
    if len(os.Args) < 2 {
        fmt.Println("请提供至少一个文件名作为参数。")
        return
    }

    for _, filename := range os.Args[1:] {
        go printFileContents(filename)
    }

    // 等待一段时间,让子goroutine完成
    time.Sleep(2 * time.Second)
}

将上述代码保存为 catfiles.go ,然后可以使用以下命令执行:

go run catfiles.go txtfile1 txtfile2 txtfile3

其中 txtfile1 txtfile2 txtfile3 是实际的文本文件名。

2、修改一个程序,使其不再接收文本文件名列表作为参数,而是接收一个目录路径。程序将查看该目录并列出其中的文件。对于每个文件,启动一个协程来搜索指定字符串的匹配。将该程序命名为grepdir.go。以下是执行此Go程序的方式:go run grepdir.go bubbles ../../commonfiles

任务描述

此题目要求修改程序,将参数从文本文件名列表改为目录路径。程序需列出目录内文件,为每个文件启动协程搜索指定字符串。

程序信息

  • 程序名称 grepdir.go
  • 运行示例 go run grepdir.go bubbles ../../commonfiles

3、将一个程序进行调整,使其能够在任何子目录中进行递归搜索。若搜索协程接收到的是一个文件,应在该文件中搜索字符串匹配;若接收到的是一个目录,应为在该目录中找到的每个文件或子目录递归地启动一个新的协程。将这个程序命名为grepdirrec.go,并通过运行命令“go run grepdirrec.go bubbles ../../commonfiles”来执行它。

程序改造要求

该要求旨在改造程序,实现对目录及其子目录的递归搜索功能。需要编写一个名为 grepdirrec.go 的程序,运行时传入搜索字符串和目录路径作为参数,程序会为每个文件和子目录启动协程进行字符串匹配搜索。

4、运行一段Go代码的竞态检测器,结果是否包含竞态条件?如果包含,能否解释其发生的原因?

结果包含竞态条件

因为代码中存在不同的 goroutine 在临界区共享资源(如内存)的情况,且没有对共享资源的访问进行同步,所以当不同的 goroutine 对共享变量进行读写操作时,就可能出现竞态条件。

例如在 stingy() spendy() 函数中对 money 变量的加减操作,就发生了竞态条件。

此外,系统差异(如处理器数量、Go版本和实现、操作系统类型等)也会影响竞态条件的发生。

5、考虑以下代码,找出此程序中的竞态条件。代码如下:```go

package main
import (
“fmt”
“time”“)
func addNextNumber(nextNum *[101]int) {
i := 0
for nextNum[i] != 0 {
i++
}
nextNum[i] = nextNum[i-1] + 1
}
func main() {
nextNum := [101]int{1}
for i := 0; i < 100; i++ {
go addNextNumber(&nextNum)
}
for nextNum[100] == 0 {
println(“Waiting for goroutines to complete”)
time.Sleep(10 * time.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值