Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
M_MMAP_THRESHOLD For allocations greater than or equal to the limit specified (in bytes) by M_MMAP_THRESHOLD that can't be satisfied from the free list, the memory-allocation functions employ mmap(2) instead of increasing the program break using sbrk(2).
man malloc
NOTES
Normally, malloc() allocates memory from the heap, and adjusts the size
of the heap as required, using sbrk(2). When allocating blocks of mem-
ory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation
allocates the memory as a private anonymous mapping using mmap(2).
MMAP_THRESHOLD is 128 kB by default, but is adjustable using mal-
lopt(3). Allocations performed using mmap(2) are unaffected by the
RLIMIT_DATA resource limit (see getrlimit(2)).
Поскольку никакой информации так и не нашел, пришлось мерить руками. Оказалось, на моей системе (3.13.0) — всего 120 байт
Unlike certain Java garbage collectors, glibc malloc does not have a feature of heap compaction. Glibc malloc does have a feature of trimming (M_TRIM_THRESHOLD); however, this only occurs with contiguous free space at the top of a heap, which is unlikely when a heap is fragmented.
TCP_QUICKACK (since Linux 2.4.4)
Enable quickack mode if set or disable quickack mode if cleared.
In quickack mode, acks are sent immediately, rather than delayed
if needed in accordance to normal TCP operation.
int main()
{
int fd = ::open("/dev/zero", O_RDONLY);
char buf[2];
cout << ::read(fd, buf, 2) << endl;
std::thread([&]() { ::close(fd); }).join();
cout << ::read(fd, buf, 2) << endl;
return 0;
}
2
-1
Если один из потоков решает закрыть свой сокет, другие потоки об этом ничего не знают, поскольку они на самом деле отдельные процессы и у них свои собственные копии этого сокета, и продолжают работать.
void reader(int fd)
{
char buf[2];
auto l=read(fd, buf, sizeof(buf));
std::cout<<l<<std::endl;
if(l > 0) close(fd);
}
int s[2];
socketpair(AF_LOCAL, SOCK_STREAM, 0, s)
char buf[2];
write(s[1], buf, sizeof buf);
std::thread t1{[=]{ reader(s[0]); }};
std::thread t2{[=]{ reader(s[0]); }};
t1.join();
t2.join();
std::thread t1{[=]{ reader(s[0]); }};
t1.join();
std::thread t2{[=]{ reader(s[0]); }};
t2.join();
А пруф где?
std::thread t1{[=]{ reader(s[0]); }};
t1.join();
std::thread t2{[=]{ reader(s[0]); }};
t2.join();
Мы уже показали что при вызове join() состояния сокетов синхронизируются.
CLONE_FILES (since Linux 2.0)
If CLONE_FILES is set, the calling process and the child process share the same file descriptor table.
Any file descriptor created by the calling process or by the child process is also valid in the other
process. Similarly, if one of the processes closes a file descriptor, or changes its associated flags
(using the fcntl(2) F_SETFD operation), the other process is also affected.
If CLONE_FILES is not set, the child process inherits a copy of all file descriptors opened in the
calling process at the time of clone(). (The duplicated file descriptors in the child refer to the
same open file descriptions (see open(2)) as the corresponding file descriptors in the calling
process.) Subsequent operations that open or close file descriptors, or change file descriptor flags,
performed by either the calling process or the child process do not affect the other process.
const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM
| CLONE_SIGHAND | CLONE_THREAD
| CLONE_SETTLS | CLONE_PARENT_SETTID
| CLONE_CHILD_CLEARTID
| 0);
#include <thread>
#include <unistd.h>
#include <iostream>
#include <mutex>
#include <sys/types.h>
#include <sys/socket.h>
void reader(int t_id, int fd)
{
char buf[2];
std::cout << t_id << ": Started" << std::endl;
auto l = read(fd, buf, 1);
std::cout << t_id << ": Received " << l << std::endl;
if (l > 0)
close(fd);
std::cout << t_id << ": Closed" << std::endl;
}
int main()
{
int s[2];
socketpair(AF_LOCAL, SOCK_STREAM, 0, s);
char buf[2] = {};
write(s[1], buf, sizeof(buf));
std::thread t1{[=]{ reader(1, s[0]); }};
std::thread t2{[=]{ reader(2, s[0]); }};
t1.join();
t2.join();
}
2: Started
2: Received 1
2: Closed
1: Started
1: Received -1
1: Closed
2: Started1: Started
1
: Received 1
1: Closed
2: Received 1
2: Closed
(gdb) info thr
Id Target Id Frame
2 Thread 0x7fe8c11e7700 (LWP 16403) 0x00007fe8c25dd3bd in read ()
at ../sysdeps/unix/syscall-template.S:81
* 1 Thread 0x7fe8c29e5780 (LWP 16401) 0x00007fe8c25d766b in pthread_join (
threadid=140637649139456, thread_return=0x0) at pthread_join.c:92
(gdb)
Плохо документированные особенности Linux