forked from kangjianwei/LearningJDK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ProcessHandle.java
469 lines (440 loc) · 20.6 KB
/
ProcessHandle.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
/**
* ProcessHandle identifies and provides control of native processes. Each
* individual process can be monitored for liveness, list its children,
* get information about the process or destroy it.
* By comparison, {@link java.lang.Process Process} instances were started
* by the current process and additionally provide access to the process
* input, output, and error streams.
* <p>
* The native process ID is an identification number that the
* operating system assigns to the process.
* The range for process id values is dependent on the operating system.
* For example, an embedded system might use a 16-bit value.
* Status information about a process is retrieved from the native system
* and may change asynchronously; processes may be created or terminate
* spontaneously.
* The time between when a process terminates and the process id
* is reused for a new process is unpredictable.
* Race conditions can exist between checking the status of a process and
* acting upon it. When using ProcessHandles avoid assumptions
* about the liveness or identity of the underlying process.
* <p>
* Each ProcessHandle identifies and allows control of a process in the native
* system. ProcessHandles are returned from the factory methods {@link #current()},
* {@link #of(long)},
* {@link #children}, {@link #descendants}, {@link #parent()} and
* {@link #allProcesses()}.
* <p>
* The {@link Process} instances created by {@link ProcessBuilder} can be queried
* for a ProcessHandle that provides information about the Process.
* ProcessHandle references should not be freely distributed.
*
* <p>
* A {@link java.util.concurrent.CompletableFuture} available from {@link #onExit}
* can be used to wait for process termination, and possibly trigger dependent
* actions.
* <p>
* The factory methods limit access to ProcessHandles using the
* SecurityManager checking the {@link RuntimePermission RuntimePermission("manageProcess")}.
* The ability to control processes is also restricted by the native system,
* ProcessHandle provides no more access to, or control over, the native process
* than would be allowed by a native application.
*
* @implSpec In the case where ProcessHandles cannot be supported then the factory
* methods must consistently throw {@link java.lang.UnsupportedOperationException}.
* The methods of this class throw {@link java.lang.UnsupportedOperationException}
* if the operating system does not allow access to query or kill a process.
*
* <p>
* The {@code ProcessHandle} static factory methods return instances that are
* <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>,
* immutable and thread-safe.
* Use of identity-sensitive operations (including reference equality
* ({@code ==}), identity hash code, or synchronization) on these instances of
* {@code ProcessHandle} may have unpredictable results and should be avoided.
* Use {@link #equals(Object) equals} or
* {@link #compareTo(ProcessHandle) compareTo} methods to compare ProcessHandles.
* @see Process
* @since 9
*/
// Java层进程句柄
public interface ProcessHandle extends Comparable<ProcessHandle> {
/**
* Returns a ProcessHandle for the current process. The ProcessHandle cannot be
* used to destroy the current process, use {@link System#exit System.exit} instead.
*
* @return a ProcessHandle for the current process
*
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @throws UnsupportedOperationException if the implementation
* does not support this operation
*/
// 返回加载ProcessHandleImpl类的进程的句柄
static ProcessHandle current() {
return ProcessHandleImpl.current();
}
/**
* Returns an {@code Optional<ProcessHandle>} for an existing native process.
*
* @param pid a native process ID
*
* @return an {@code Optional<ProcessHandle>} of the PID for the process;
* the {@code Optional} is empty if the process does not exist
*
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @throws UnsupportedOperationException if the implementation
* does not support this operation
*/
// 返回进程号为pid的进程句柄
static Optional<ProcessHandle> of(long pid) {
return ProcessHandleImpl.get(pid);
}
/**
* Returns a snapshot of all processes visible to the current process.
* <p>
* <em>Note that processes are created and terminate asynchronously. There
* is no guarantee that a process in the stream is alive or that no other
* processes may have been created since the inception of the snapshot.
* </em>
*
* @return a Stream of ProcessHandles for all processes
*
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @throws UnsupportedOperationException if the implementation
* does not support this operation
*/
// 返回所有已知进程
static Stream<ProcessHandle> allProcesses() {
return ProcessHandleImpl.children(0);
}
/**
* Returns an {@code Optional<ProcessHandle>} for the parent process.
* Note that Processes in a zombie state usually don't have a parent.
*
* @return an {@code Optional<ProcessHandle>} of the parent process;
* the {@code Optional} is empty if the child process does not have a parent
* or if the parent is not available, possibly due to operating system limitations
*
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
*/
// 返回当前进程的父进程句柄
Optional<ProcessHandle> parent();
/**
* Returns a snapshot of the current direct children of the process.
* The {@link #parent} of a direct child process is the process.
* Typically, a process that is {@link #isAlive not alive} has no children.
* <p>
* <em>Note that processes are created and terminate asynchronously.
* There is no guarantee that a process is {@link #isAlive alive}.
* </em>
*
* @return a sequential Stream of ProcessHandles for processes that are direct children of the process
*
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
*/
// 返回当前进程的直接子进程
Stream<ProcessHandle> children();
/**
* Returns a snapshot of the descendants of the process.
* The descendants of a process are the children of the process plus the descendants of those children, recursively.
* Typically, a process that is {@link #isAlive not alive} has no children.
* <p>
* <em>
* Note that processes are created and terminate asynchronously.
* There is no guarantee that a process is {@link #isAlive alive}.
* </em>
*
* @return a sequential Stream of ProcessHandles for processes that are descendants of the process
*
* @throws SecurityException if a security manager has been installed and it denies RuntimePermission("manageProcess")
*/
// 返回当前进程的后代进程
Stream<ProcessHandle> descendants();
/**
* Returns a {@code CompletableFuture<ProcessHandle>} for the termination
* of the process.
* The {@link java.util.concurrent.CompletableFuture} provides the ability
* to trigger dependent functions or actions that may be run synchronously
* or asynchronously upon process termination.
* When the process has terminated the CompletableFuture is
* {@link java.util.concurrent.CompletableFuture#complete completed} regardless
* of the exit status of the process.
* The {@code onExit} method can be called multiple times to invoke
* independent actions when the process exits.
* <p>
* Calling {@code onExit().get()} waits for the process to terminate and returns
* the ProcessHandle. The future can be used to check if the process is
* {@link java.util.concurrent.CompletableFuture#isDone done} or to
* {@link java.util.concurrent.Future#get() wait} for it to terminate.
* {@link java.util.concurrent.Future#cancel(boolean) Cancelling}
* the CompleteableFuture does not affect the Process.
*
* @return a new {@code CompletableFuture<ProcessHandle>} for the ProcessHandle
*
* @throws IllegalStateException if the process is the current process
* @apiNote The process may be observed to have terminated with {@link #isAlive}
* before the ComputableFuture is completed and dependent actions are invoked.
*/
/*
* 返回一个阶段:该阶段的执行结果是当前进程退出时的状态码(如果没执行完,则会等待它执行完);
* 该方法可以看做是【异步】等待进程结束的一种手段。
*
* 如果等待进程结束的过程中抛出了中断异常,则会为执行该阶段任务的线程设置中断标记。
*/
CompletableFuture<ProcessHandle> onExit();
/**
* Returns the native process ID of the process. The native process ID is an
* identification number that the operating system assigns to the process.
* The operating system may reuse the process ID after a process terminates.
* Use {@link #equals(Object) equals} or
* {@link #compareTo(ProcessHandle) compareTo} to compare ProcessHandles.
*
* @return the native process ID of the process
*
* @throws UnsupportedOperationException if the implementation
* does not support this operation
*/
// 返回当前进程的进程号
long pid();
/**
* Returns a snapshot of information about the process.
*
* <p> A {@link ProcessHandle.Info} instance has accessor methods that return
* information about the process if it is available.
*
* @return a snapshot of information about the process, always non-null
*/
// 返回当前进程的快照信息
Info info();
/**
* Tests whether the process represented by this {@code ProcessHandle} is alive.
* Process termination is implementation and operating system specific.
* The process is considered alive as long as the PID is valid.
*
* @return {@code true} if the process represented by this
* {@code ProcessHandle} object has not yet terminated
*/
// 判断当前进程是否处于活动状态
boolean isAlive();
/**
* Returns {@code true} if the implementation of {@link #destroy}
* normally terminates the process.
* Returns {@code false} if the implementation of {@code destroy}
* forcibly and immediately terminates the process.
*
* @return {@code true} if the implementation of {@link #destroy}
* normally terminates the process;
* otherwise, {@link #destroy} forcibly terminates the process
*/
// 返回当前平台对结束进程的支持状况;返回true表示支持正常终止,返回false表示支持强制终止
boolean supportsNormalTermination();
/**
* Requests the process to be killed.
* Whether the process represented by this {@code ProcessHandle} object is
* {@link #supportsNormalTermination normally terminated} or not is
* implementation dependent.
* Forcible process destruction is defined as the immediate termination of the
* process, whereas normal termination allows the process to shut down cleanly.
* If the process is not alive, no action is taken.
* The operating system access controls may prevent the process
* from being killed.
* <p>
* The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
* {@link java.util.concurrent.CompletableFuture#complete completed}
* when the process has terminated.
* <p>
* Note: The process may not terminate immediately.
* For example, {@code isAlive()} may return true for a brief period
* after {@code destroy()} is called.
*
* @return {@code true} if termination was successfully requested,
* otherwise {@code false}
*
* @throws IllegalStateException if the process is the current process
*/
// 终止当前进程;如果当前进程是加载ProcessHandleImpl类的进程,则无法销毁
boolean destroy();
/**
* Requests the process to be killed forcibly.
* The process represented by this {@code ProcessHandle} object is
* forcibly terminated.
* Forcible process destruction is defined as the immediate termination of the
* process, whereas normal termination allows the process to shut down cleanly.
* If the process is not alive, no action is taken.
* The operating system access controls may prevent the process
* from being killed.
* <p>
* The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
* {@link java.util.concurrent.CompletableFuture#complete completed}
* when the process has terminated.
* <p>
* Note: The process may not terminate immediately.
* For example, {@code isAlive()} may return true for a brief period
* after {@code destroyForcibly()} is called.
*
* @return {@code true} if termination was successfully requested,
* otherwise {@code false}
*
* @throws IllegalStateException if the process is the current process
*/
// 强制终止当前进程;如果当前进程是加载ProcessHandleImpl类的进程,则无法销毁
boolean destroyForcibly();
/**
* Returns a hash code value for this ProcessHandle.
* The hashcode value follows the general contract for {@link Object#hashCode()}.
* The value is a function of the {@link #pid pid()} value and
* may be a function of additional information to uniquely identify the process.
* If two ProcessHandles are equal according to the {@link #equals(Object) equals}
* method, then calling the hashCode method on each of the two objects
* must produce the same integer result.
*
* @return a hash code value for this object
*/
@Override
int hashCode();
/**
* Returns {@code true} if {@code other} object is non-null, is of the
* same implementation, and represents the same system process;
* otherwise it returns {@code false}.
*
* @param other another object
*
* @return {@code true} if the {@code other} object is non-null,
* is of the same implementation class and represents
* the same system process; otherwise returns {@code false}
*
* @implNote It is implementation specific whether ProcessHandles with the same PID
* represent the same system process. ProcessHandle implementations
* should contain additional information to uniquely identify the process.
* For example, the start time of the process could be used
* to determine if the PID has been re-used.
* The implementation of {@code equals} should return {@code true} for two
* ProcessHandles with the same PID unless there is information to
* distinguish them.
*/
@Override
boolean equals(Object other);
/**
* Compares this ProcessHandle with the specified ProcessHandle for order.
* The order is not specified, but is consistent with {@link Object#equals},
* which returns {@code true} if and only if two instances of ProcessHandle
* are of the same implementation and represent the same system process.
* Comparison is only supported among objects of same implementation.
* If attempt is made to mutually compare two different implementations
* of {@link ProcessHandle}s, {@link ClassCastException} is thrown.
*
* @param other the ProcessHandle to be compared
*
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
*
* @throws NullPointerException if the specified object is null
* @throws ClassCastException if the specified object is not of same class
* as this object
*/
@Override
int compareTo(ProcessHandle other);
/**
* Information snapshot about the process.
* The attributes of a process vary by operating system and are not available
* in all implementations. Information about processes is limited
* by the operating system privileges of the process making the request.
* The return types are {@code Optional<T>} allowing explicit tests
* and actions if the value is available.
*
* @since 9
*/
interface Info {
/**
* Returns the executable pathname of the process.
*
* @return an {@code Optional<String>} of the executable pathname
* of the process
*/
Optional<String> command();
/**
* Returns the command line of the process.
* <p>
* If {@link #command command()} and {@link #arguments arguments()} return
* non-empty optionals, this is simply a convenience method which concatenates
* the values of the two functions separated by spaces. Otherwise it will return a
* best-effort, platform dependent representation of the command line.
*
* @return an {@code Optional<String>} of the command line
* of the process
*
* @apiNote Note that the returned executable pathname and the
* arguments may be truncated on some platforms due to system
* limitations.
* <p>
* The executable pathname may contain only the
* name of the executable without the full path information.
* It is undecideable whether white space separates different
* arguments or is part of a single argument.
*/
Optional<String> commandLine();
/**
* Returns an array of Strings of the arguments of the process.
*
* @return an {@code Optional<String[]>} of the arguments of the process
*
* @apiNote On some platforms, native applications are free to change
* the arguments array after startup and this method may only
* show the changed values.
*/
Optional<String[]> arguments();
/**
* Returns the start time of the process.
*
* @return an {@code Optional<Instant>} of the start time of the process
*/
Optional<Instant> startInstant();
/**
* Returns the total cputime accumulated of the process.
*
* @return an {@code Optional<Duration>} for the accumulated total cputime
*/
Optional<Duration> totalCpuDuration();
/**
* Return the user of the process.
*
* @return an {@code Optional<String>} for the user of the process
*/
Optional<String> user();
}
}