fwrite()失败:EDC5024i:试图关闭在另一个线程中打开的文件 [英] fwrite() failed : EDC5024i:An attempt was made to close a file that had been open in another thread

查看:134
本文介绍了fwrite()失败:EDC5024i:试图关闭在另一个线程中打开的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在提交JCL作业以在大型机中分配VB数据集.提交作业后,将成功创建数据集.

I am submitting a JCL job to allocate a VB dataset in Mainframe. After submitting the job, the dataset gets created successfully.

然后,我在大型机的omvs区域中运行一个Java程序,以打开文件并向其中写入一些内容.当我尝试将数据写入文件时,出现以下错误.

Then I am running a java program in omvs region of mainframe, to open the file and write some contents into it. When I try to write the data into the file I am getting the below error.

//DD:SYS00011:fwrite()失败. EDC5024I试图关闭由另一个线程打开的文件. errno = 24 errno2 = 0xc0640021 last_op = 0 errorCode = 0x0.

//DD:SYS00011 : fwrite() failed. EDC5024I An attempt was made to close a file that had been opened by another thread.; errno=24 errno2=0xc0640021 last_op=0 errorCode=0x0.

JCL已提交以分配数据集:

JCL submitted to allocate the dataset:

//USERNAME JOB ABC,,NOTIFY=&SYSUID,CLASS=F,MSGLEVEL=(1,1),MSGCLASS=X 
//STEP1 EXEC PGM=IEFBR14 
//STEP DD DSN=ASD00T.SM.ULRL, 
// DISP=(NEW,CATLG,DELETE), 
// UNIT=SYSDA,SPACE=(1,(10,60),RLSE),AVGREC=M, 
// DCB=(RECFM=VB), 
// DSORG=PS

写入文件的代码:

zFileIn = new ZFile("//'ASD00T.INPUT.ULRL'", "rb,type=record,noseek");
if (zFileIn.getDsorg() != ZFile.DSORG_PS) {
throw new IllegalStateException("Input dataset must be DSORG=PS");
 }
zFileOut = new ZFile("//'ASD00T.SM.ULRL'", "wb,type=record,noseek, recfm="+ zFileIn.getRecfm()+ ", lrecl="+ zFileIn.getLrecl());
long count = 0;
byte[] recBuf = new byte[zFileIn.getLrecl()];
int nRead;
while((nRead = zFileIn.read(recBuf)) >= 0) {
zFileOut.write(recBuf, 0, nRead);
count++;
}

推荐答案

问题的核心是编写完成后需要调用ZFile.close()方法.这样做将确保打开,写入和关闭操作均在同一线程下进行,并且您应该没事.这是使用常规数据集而不是USS文件的副作用.

The heart of your problem is that you need to invoke the ZFile.close() method after you're done writing. Doing so will guarantee that the open, writes and close all happen under the same thread and you should be fine. This is a side-effect of using conventional datasets instead of USS files.

其原因很复杂,但这与z/OS中的常规" QSAM/BSAM/VSAM数据集的行为与UNIX文件系统文件略有不同的事实有关.

The reason for this is complicated, but it has to do with the fact that in z/OS, "conventional" QSAM/BSAM/VSAM datasets behave slightly differently than do UNIX filesystem files.

如果您要写的是UNIX文件(HFS,ZFS,NFS等)而不是常规数据集,那么您所做的工作就可以很好地工作了……这是因为USS对待资源所有权的方式有所不同-文件句柄是在进程级别拥有,而不是线程.当您打开USS文件时,该文件句柄可以被进程中的任何线程使用或关闭...这是各种UNIX标准所强制要求的,因此z/OS别无选择,只能以这种方式工作.

If you were writing to a UNIX file (HFS, ZFS, NFS, etc) instead of a conventional dataset, what you're doing would work perfectly fine...this is because USS treats resource ownership differently - file handles are owned at a process level, not a thread. When you open a USS file, that file handle can be used or closed by any thread in the process...this is mandated by the various UNIX standards, so z/OS has no choice but to work this way.

常规数据集有些不同.当您打开常规数据集时,定义打开文件的操作系统结构将存储在定位到打开文件线程的内存中.文件句柄中有足够的信息,您可以从其他线程进行I/O,但是关闭文件需要在打开文件的线程中进行.

Conventional datasets are a bit different. When you open a conventional dataset, the operating system structures that define the open file are stored in memory anchored to the thread where the file was opened. There's enough information in the file handle that you can do I/O from other threads, but closing the file needs to happen from the thread where the file was opened.

现在,由于您的代码中似乎没有close(),因此该文件将保持打开状态,直到您的Java线程结束.当Java线程结束时,系统运行时将获得控制权,以清理您可能已分配的任何资源.它会看到挥之不去的打开文件并尝试关闭它,但是现在它不在打开文件的线程下运行,因此您会看到失败.

Now, since you don't seem to have a close() in your code, the file stays open until your Java thread ends. When your Java thread ends, the system runtime gets control in order to clean up any resources you might have allocated. It sees the lingering open file and tries to close it, but now it's not running under the thread that opened the file, so you get the failure you're seeing.

通常,UNIX文件和z/OS数据集的工作原理几乎完全相同,但是此问题只是其中的微小差异之一.因为z/OS数据集不是任何标准的一部分,所以IBM从标准合规性的角度出发摆脱了这一障碍,通常,它们可以互换使用的方式是一个很棒的功能.

Normally, UNIX files and z/OS datasets work almost exactly the same, but this issue is one of the slight differences. IBM gets away with it from a standards compliance perspective since z/OS datasets aren't part of any standard, and generally, the way they can be used interchangeably is a great feature.

顺便说一下,所有这些都在LE(语言环境)和C运行时引用的精巧版中清楚地说明了.

By the way, all of this is spelled out in the fine print of the LE (Language Environment) and C Runtime references.

这篇关于fwrite()失败:EDC5024i:试图关闭在另一个线程中打开的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆