关于多进程处理某一资源的共享问题,请大家给点意见

goodfood 2002-05-07 09:54:25
// 问题描述:

N个进程,同时对一批文件进行处理,如何才能保证这批文件不会被重复处理?

一般来说,设置一个共享标志,用来标明某个文件是否正在处理,或者已经被处理,

这样做的话,有两个步骤是必须的:

1) 判断共享标志(该共享资源是否被处理);

2) 根据判断结果作出相应的动作;

// 问题在于:

进程1,在进行步骤1)完毕后,进程1的时间片完了,被挂起,进程2开始进行步

骤1),会得到和进程1)相同的结果,那会造成两个进程同时访问一个共享资源。

到底有没有方法,可以使 判断共享标志 和 置共享标志 这两个步骤成为一个原子

操作呢?

请各位指点!!!!!!!!
...全文
270 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Last_Dodo 2002-05-09
  • 打赏
  • 举报
回复
首先,mutex是进程内的锁,不能被进程共享,所以必须用进程间共享的锁。如果你的系统支持flock,你可以用它不必考虑semaphore一类的问题,所以会简单得多。举个简单的例子:

bool processFilesInADirectory()
{
extern bool processAFile(const char *fileName);
DIR *dir = opendir(".");
if (!dir) {
perror("Can not open current directory: ");
return false;
}
dirent *entry = readdir(dir);
while (entry){
if (!processAFile(entry->d_name)) return false;
entry = readdir(dir);
}
return true;
};

bool processAFile(const char *fileName)
{
if (!fileName) return false;
int fd = open(fileName, O_RDWR);
if (fd < 0) {
char msg[1024];
sprintf(msg, "Cannot open file [%s]", fileName);
perror(msg);
return false;
}

#ifdef FLOCK_SUPPORTED
if (flock(fd, LOCK_EX) < 0) return true; //somebody is working on it
#else
if (flock(fd, fileName) < 0) return true;
#endif

//do your file processing here;
return true;
}

如果没有flock,则自己用semaphore写一个,不过得注意程序因任何原因结束时都得把semaphore释放(不管任何原因程序结束,flock都会把那锁释放)。
ryan_chen 2002-05-09
  • 打赏
  • 举报
回复
我曾经问过一个高手,他说信号量也不行,我对信号量理解不深,他讲的理由我也不大记得了,所以还请说明
可能他描述的或思考的是线程共享的信号灯,用进程共享的信号灯一定可以的。

简单的方法,不用去学什么信号灯:
进程到指定目录取文件,然后移动文件到temp目录后处理该文件(returncode = system("mv a.file temp/a.file"))。注意判断returncode.
一定满足你的需求。不信你试试,操作系统会帮你保证移动的一致性,一旦a进程移动成功,说明它取得了文件的操作权。
就算2个以上进程同时执行该语句,返回成功的只有一个,它接着处理。其他进程接着竞争下一个文件。
freezingfire 2002-05-08
  • 打赏
  • 举报
回复
个人理解,信号量应该可以。加锁后,即使进程时间片到被挂起,共享资源仍旧处于被锁状态,其他进程访问不了的。
goodfood 2002-05-08
  • 打赏
  • 举报
回复
多谢以上几位的回复,我研究一下。

希望各位高手多多解答!
hongbo_liu 2002-05-08
  • 打赏
  • 举报
回复
非常简单,定义一个结构:
STRUCT A{
CHAR FILENAME[200];
PTHREAD_MUTEX A_MUTEX;
INT FLAG;
STRUCT A *NEXT;
}
每次处理文件时,先将其读入一个连表中,多个进程处理时,先对某个接点加锁,判断FLAG(0 没处理,1 已处理),如是没处理 ,则改变FLAG值为1,解锁并处理文件,否则解锁,找下一个接点重复以上动作。
cool_killer 2002-05-08
  • 打赏
  • 举报
回复
用一个信号灯就可以了
假设共有n个文件,定一个数组short int i_state[n]代表每一个文件的状态(0.未处理,1.处理中,2.处理完)。
先将i_state所有值初始为0。
定义一个信号等mutex初始值为1。以下用PV操作,对每个进程执行以下过程。
while(1){
P(mutex);
for( i = 0;i<n;i++)
{
if(i_state[i]==0)
break;
}
if(i>=n){ //处理文件完毕
V(mutex);
exit(0);
}
i_state[i] = 1;
V(mutex);
...处理文件...
i_state[i] = 2;
}
goodfood 2002-05-07
  • 打赏
  • 举报
回复
我认为关键问题是:判断 和 设置 这两个步骤能不能是一个原子操作?
goodfood 2002-05-07
  • 打赏
  • 举报
回复
我认为关键问题是:判断 和 设置 这两个步骤能不能是一个原子操作?
goodfood 2002-05-07
  • 打赏
  • 举报
回复
我曾经问过一个高手,他说信号量也不行,我对信号量理解不深,他讲的理由我也

不大记得了,所以还请说明。

另:stevens的那本unix网络编程我正在看,感觉浩瀚如海,而且项目时间比较

紧,所以请高手指个方向,使我有针对性的学习,当然如果能提出个解决方案让我

应付先,我更是感激。

晨星 2002-05-07
  • 打赏
  • 举报
回复
设置一个信号量,任何进程在使用文件前对信号量加锁,然后都完成了才解锁。因为我觉得1,2两步是不可分的。
晨星 2002-05-07
  • 打赏
  • 举报
回复
使用信号量不行吗?

69,377

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧