gpt4 book ai didi

具有 CLONE_FILES 泄漏 fcntl 锁的克隆(2)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:26:13 26 4
gpt4 key购买 nike

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define __USE_GNU
#include <sched.h>

void init_lock(struct flock *f)
{
f->l_type = F_WRLCK; /* write lock set */
f->l_whence = SEEK_SET;
f->l_start = 0;
f->l_len = 0;
f->l_pid = getpid();
}

int lock(int fd, struct flock *f)
{
init_lock(f);
if(fcntl(fd, F_SETLKW, f) == -1) {
fprintf(stderr,"fcntl() failed: %s\n", strerror(errno));
return -1;
}
return 0;
}

int unlock(int fd, struct flock *f)
{
f->l_type = F_UNLCK;
if(fcntl(fd, F_SETLK, f) == -1) {
fprintf(stderr, "fcntl() failed: %s\n", strerror(errno));
return -1;
}
return 0;
}

int file_op(void *arg)
{
char buff[256];
int fd = (int) arg, n;
struct flock my_lock;

printf("Trying to get lock\n");
if(lock(fd, &my_lock) == -1) { /* lock acquired by a thread */
return -1;
}

printf("Got lock: %d\n", getpid()); /* I am printing thread id after lock() */
printf("Enter string to write in file : ");
scanf("%s", buff);

if((n=write(fd, &buff, strlen(buff))) == -1) {
fprintf(stderr, "write() failed: %s\n", strerror(errno));
}

if(unlock(fd, &my_lock) == -1) {
return -1;
}
printf("Lock Released: %d\n", getpid());
return 0;
}

int main()
{
char *stack;
int fd, i=0, cid, stacksize;

if((fd = open("sample.txt", O_CREAT | O_WRONLY | O_APPEND, 0644)) == -1) {
printf("Error in file opening\n");
exit(1);
}

stacksize = 3*1024*1024;
for(i=0; i<5; i++) {
stack = malloc(stacksize);
if((cid = clone(&file_op, stack + stacksize, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD, (void *) fd)) == -1) {
fprintf(stderr,"clone() failed: %s\n", strerror(errno));
break;
}
}
sleep(30);
close(fd);
return 0;
}

我希望每个 clone() 都将等待锁定。但是这段代码的输出(类似这样的东西):

Trying to get lock
Trying to get lock
Trying to get lock
Got lock: Got lock: 10287
Got lock: Got lock: 10287

Enter string to write in file : Trying to get lock
Enter string to wriGot lock: 10287
Got lock: 10287
Got lock: 10287
Enter string to write in file : Trying to get lock
Got lock: 10287
Got lock: Enter string to write in file :

但是当我从 clone(2) 中删除 CLONE_FILES 字段集时,一切顺利。其他克隆线程将等待 lock()。

输出:

Trying to get lock
Got lock: 10311
Trying to get lock
Trying to get lock
Trying to get lock
Trying to get lock

还有其他选择(使用 CLONE_FILES)吗?为什么会出现这种行为?

该领域的初学者。

最佳答案

flock 提供的锁定是针对每个进程的,而不是针对每个线程的。

来自 http://linux.die.net/man/2/flock (强调我的):

A call to flock() may block if an incompatible lock is held by another process.

Subsequent flock() calls on an already locked file will convert an existing lock to the new lock mode.

Locks created by flock() are associated with an open file table entry.

虽然没有明确提到线程,但多个线程共享一个文件表条目,而多个进程则没有。将 CLONE_FILES 传递给 clone 会导致您的“进程”共享文件表。

一个解决方案可能是调用dup 来生成更多的文件描述符。来自文档:

If a process uses open(2) (or similar) to obtain more than one descriptor for the same
file, these descriptors are treated independently by flock(). An attempt to lock the file using one of these file descriptors may be denied by a lock that the calling process has already placed via another descriptor.

关于具有 CLONE_FILES 泄漏 fcntl 锁的克隆(2)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12197258/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com