【问题标题】:how to do two threads can not acces the same folder两个线程不能访问同一个文件夹怎么办
【发布时间】:2014-09-03 12:34:41
【问题描述】:

我正在编写一个多线程应用程序,它是 Windows 服务。我有 20 个文件夹。我创建了 15 个线程的 onstart 方法。我想实现这一目标; 15 个线程依次转到文件夹 1、2、3、...、15。当一个线程完成时,它会创建另一个线程。这个创建的线程必须去 16.th 文件夹。它不能进入​​工作文件夹。我怎样才能做到这一点?也就是说,我怎么能确定两个线程不会去同一个文件夹呢?

【问题讨论】:

  • 您的意思是每 15 个文件夹有 15 个线程,还是每个线程一个文件夹。如果是后者,为什么需要线程来实现同步?
  • 我的意思是每个线程一个文件夹。
  • 只是传递一个参数来确定数量。或者使用parallelfor
  • 并行创建 15 个线程是不可能的。我认为。
  • 是的,我的 Task 解决方案可能并没有真正在 15 个线程上运行。默认情况下,Tasks 使用线程数有限的线程池(尽管您可以设置自己的最大线程数)。无论如何,即使您自己创建了线程,您也可以为文件夹名称创建一个静态计数器。

标签: c# multithreading


【解决方案1】:

你能不能只用一个静态变量作为文件夹名称的计数器?

类似:

private static int _folderNameCounter = 0;
private static readonly object _padlock = new object();
public static int GetFolderCounter()
{
     lock(_padlock)
     {
         _folderNameCounter++;
         return _folderNameCounter;
     }
}

public static void Main()
{
        for(int i = 0; i < 20; i++)
        {

            Task.Factory.StartNew(() => 
             {
                var path = @"c:\temp\" + GetFolderCounter();
                Directory.CreateDirectory(path);
                // add your own code for the thread here
             });
        }

}

【讨论】:

  • 不,它并没有真正启动 20 个线程。任务调度器确定有多少。如果您“明确”想要启动 20 个线程,您可以为 Task.Factory.StartNew 指定 TaskCreationOptions.LongRunning 选项,(似乎不能 100% 保证您获得那么多线程):stackoverflow.com/questions/13570579/…
【解决方案2】:

注意:我使用TPL 而不是直接使用线程,因为我认为the TPL is a better solution。您当然可以有特定的要求,这可能意味着线程是更好的解决方案 你的情况。

使用BlockingCollection&lt;T&gt; 并用文件夹编号填充集合。每个任务处理集合的一个项目,集合本身处理多线程方面,因此每个项目仅由一个消费者处理。

// Define the blocking collection with a maximum size of 15.
const int maxSize = 15;
var data = new BlockingCollection<int>(maxSize);

// Add the data to the collection.
// Do this in a separate task since BlockingCollection<T>.Add()
// blocks when the specified capacity is reached.
var addingTask = new Task(() => {
    for (int i = 1; i <= 20; i++) {
        data.Add(i);
    }
).Start();

// Define a signal-to-stop bool
var stop = false;

// Create 15 handle tasks.
// You can change this to threads if necessary, but the general idea is that
// each consumer continues to consume until the stop-boolean is set.
// The Take method returns only when an item is/becomes available.
for (int t = 0; t < maxSize; t++) {
    new Task(() => {
        while (!stop) {
            int item = data.Take();
            // Note: the Take method will block until an item comes available.
            HandleThisItem(item);
        }
    }).Start();
};

// Wait until you need to stop. When you do, set stop true
stop = true;

【讨论】:

    猜你喜欢
    • 2013-10-20
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    相关资源
    最近更新 更多