-1

我想创建一个程序,使用 POSIX 线程,让n线程以不同的优先级运行。

m这些n线程之间共享一些文件(例如文件)。如果一个线程正在使用该文件(假设它正在写入该文件),则不允许其他线程使用它。代码应该维护一个表,该表告诉:它已获取哪个文件以及它的请求正在等待哪个文件。

此外,我们需要一个监视器线程来检查死锁;任何实现提示/想法?

4

3 回答 3

1

您不需要检查死锁。您必须编写一个很好的代码,使其不可能陷入死锁场景。出于这个原因,我建议您使用 try-lock 方法来锁定文件链并在任何锁定获取失败时将它们解锁。

ftrylockfile此外,如果您使用 C 缓冲 I/O ,funlockfile我建议您坚持使用API。否则,请使用最适合您的情况的同步机制,即 futex API 或使用原子指令实现的锁。

于 2012-10-18T19:37:46.930 回答
1

完成此操作的标准 unix 方法是:spooldirectories。

  • 文件操作,例如重命名/链接/取消链接是原子的
  • 有一个中央输入 spool-dir,可以放置输入文件
  • 想要处理文件的进程/线程,首先将其移动到另一个名称,或者更好:移动到另一个(工作)目录(使用 thread_id 或进程号作为目录名称是显而易见的。)
  • (因为这个动作是原子的,所以不可能有竞争条件!)
  • 处理后,完成的文件可以移动到输出目录
  • scoreboard函数只是工作目录上的readdir(+stat),甚至可能是 inotify
  • 进程饥饿将永远是一个问题。未完全处理的文件将永远存在于 de workdirs 中。在工作目录中有一个 stamp/pid 文件可以帮助清理/重新启动。
  • 如果设计得好,即使机器发生故障,这种结构也能正常工作。工作人员必须维护自己的备份/日志/stamp-file 机制。
  • 如果您还没有注意到:不需要锁定。
于 2012-10-18T22:29:45.027 回答
0

I hate C. I have to try and think of a way to do this without classes:(

OK, a 'Sfile' struct to represent each file. Has name, path, file fd/handle, everything to do with one file, plus an 'inUse' boolean.

A 'waitingThreads' array for those threads waiting for a set of files.

A 'Sfiles' struct with an array of *Sfile to hold all the files, a waitingThreads array and a lock, (mutex/futex/criticalSection).

Each thread should have an event/semaphore/something that it can wait on until its files all become available and some way to access to the set of files that it needs and somewhere to store the fds/handles/whatever for the files.

OK, off we go:

Any thread that wants files locks up the Sfiles and iterates the *Sfile array, checking if every file it needs is free to use. If they all are, it sets the 'inUse' boolean, loads itself up with the fd/handles, unlocks and runs on - it has all its files. If any file it needs is in use, it pushes itself onto the waitingThreads array and waits on its event/sema.

Whne a thread is done with its files, it locks the Sfiles and clears the 'inUse' boolean for the files it was using. It then iterates the waitingThreads array - if the array is empty, it just unlocks and exits. If the array is not empty, it tries to find threads that can now run with the files that are now free. If it finds none, it just unlocks and returns. If it does find one, it loads that thread up with the fd/handles, sets the inUse boolean and signals its event/sema - that thread will then run with its desired set of files. The thread continues to iterate the waitingThreads array to the end, looking for mre threads that it can load up and signal with the remaining free files. When it reaches the end of the array, it returns.

That, or something like it, will ensure that the threads always run with their complete set of files, prevent any deadlocks due to threads locking partial sets of files and does not require any polling.

If you really, really need that table thingy, you can build it inside the lock every time a thread enters or leaves the lock. I would suggest mallocing a suitable struct, loading it up with all the details of the free files and waiting threads, and queueing it off to another thread. You could just have some 'monitoring' thread that periodically locks up the Sfiles, dumps all the info and unlocks, but that keeps the Sfiles locked for the entire 'dump' time - you may not want that overhead - it's up to you.

Edit:

OH - forgot the priority thingy. The OS thread priority is probably useless for your purpose. Have each thread expose a priority enum/int and keep the 'waitingThreads' array sorted by that priority, so giving the higher priority threads the first bite at whatever files are returned.

Is that good enough for your homework assignment?

于 2012-10-18T20:37:52.487 回答