#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ProcessState {
Ready,
Running,
Waiting,
Terminated,
}
#[derive(Debug)]
struct Process {
pid: usize,
state: ProcessState,
}
struct Scheduler {
processes: Vec<Process>,
current_index: usize,
}
impl Scheduler {
fn new(processes: Vec<Process>) -> Self {
Scheduler {
processes,
current_index: 0,
}
}
fn schedule(&mut self) -> Option<&Process> {
if self.processes.is_empty() {
return None;
}
let len = self.processes.len();
for _ in 0..len {
self.current_index = (self.current_index + 1) % len;
let proc = &mut self.processes[self.current_index];
if proc.state == ProcessState::Ready {
proc.state = ProcessState::Running;
return Some(proc);
}
}
None
}
fn update_state(&mut self, pid: usize, new_state: ProcessState) {
if let Some(proc) = self.processes.iter_mut().find(|p| p.pid == pid) {
proc.state = new_state;
}
}
}
fn main(){
let mut scheduler = Scheduler::new(vec![
Process { pid: 1, state: ProcessState::Ready},
Process { pid: 2, state: ProcessState::Ready},
Process { pid: 3, state: ProcessState::Waiting},
]);
for _ in 0..5 {
if let Some(proc) = scheduler.schedule() {
println!("Running process: {:?}", proc.pid);
scheduler.update_state(proc.pid, ProcessState::Ready);
} else {
println!("No Runnable processes.");
break;
}
}
}
Month: May 2025
【Rust】メモリ管理
const FRAME_SIZE: usize = 4096;
const TOTAL_MEMORY: usize = 1024 * 1024 * 128;
const TOTAL_FRAMES: usize = TOTAL_MEMORY / FRAME_SIZE;
static mut FRAME_BITMAP: [bool; TOTAL_FRAMES] = [false; TOTAL_FRAMES];
pub struct FrameAllocator;
impl FrameAllocator {
pub fn alloc() -> Option<usize> {
unsafe {
for (i, used) in FRAME_BITMAP.iter_mut() enumerate() {
if !*used {
*used = true;
return Some(i * FRAME_SIZE);
}
}
None
}
}
pub fn dealloc(addr: usize) {
let index = addr / FRAME_SIZE;
if index < TOTAL_FRAMES {
unsafe {
FRAME_BITMAP[index] = false;
}
}
}
}
【Rust】バイナリデータへの処理
### 文字列の変換
fn main() {
let text = "Hello, Rust!";
let binary = text.as_bytes();
println!("binary: {:?}", binary);
}
binary: [72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33]
### テキストファイルの変換
input.txt
Hello Rust! This is sample
use std::fs::File;
use std::io::{self, Read, Write};
fn main() -> io::Result<()>{
let mut input_file = File::open("./data/input.txt")?;
let mut buffer = Vec::new();
input_file.read_to_end(&mut buffer)?;
println!("binary: {:?}", &buffer);
Ok(())
}
### データのchunk
fn main(){
let data = vec![0u8; 10000];
let chunk_size = 1024;
for(i, chunk) in data.chunks(chunk_size).enumerate() {
println!("チャンク {}: サイズ = {}", i, chunk.len());
}
}
チャンク 0: サイズ = 1024
チャンク 1: サイズ = 1024
チャンク 2: サイズ = 1024
チャンク 3: サイズ = 1024
チャンク 4: サイズ = 1024
チャンク 5: サイズ = 1024
チャンク 6: サイズ = 1024
チャンク 7: サイズ = 1024
チャンク 8: サイズ = 1024
チャンク 9: サイズ = 784
### 画像データのchunk
use std::fs::File;
use std::io::{self, Read, Write};
fn main()-> io::Result<()>{
let mut input_file = File::open("./data/test.jpg")?;
let mut buffer = Vec::new();
input_file.read_to_end(&mut buffer)?;
let chunk_size = 1024;
for(i, chunk) in buffer.chunks(chunk_size).enumerate() {
println!("チャンク {}: 値 = {:?}", i, chunk);
}
Ok(())
}
Rustでmalloc, free
use std::alloc::{alloc, dealloc, Layout};
use std::ptr;
fn main() {
unsafe {
let layout = Layout::new::<i32>();
let ptr = alloc(layout) as *mut i32;
if ptr.is_null() {
panic!("メモリ確保に失敗しました");
}
*ptr = 42;
println!("ptrが指す値: {}", *ptr);
dealloc(ptr as *mut u8, layout);
}
}
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.83s
Running `target/debug/memory`
ptrが指す値: 42
【Blockchain】storjをpythonで実装する
import os
from cryptography.fernet import Fernet
from reedsolo import RSCodec
CHUNK_SIZE = 32
DATA_SEGMENTS = 4
TOTAL_SEGMENTS = 8
rsc = RSCodec(TOTAL_SEGMENTS - DATA_SEGMENTS)
key = Fernet.generate_key()
cipher = Fernet(key)
original_data = b"StorjTestData1234567890!ThisIsAChunkTestFile!!"
print(f"元データ: {original_data}")
encrypted_data = cipher.encrypt(original_data)
print(f"暗号化データ: {encrypted_data}")
chunks = [encrypted_data[i:i+CHUNK_SIZE] for i in range(0, len(encrypted_data), CHUNK_SIZE)]
def encode_chunk(chunk):
encoded = rsc.encode(chunk)
seg_size = len(encoded) // TOTAL_SEGMENTS
return [encoded[i:i+seg_size] for i in range(0, len(encoded), seg_size)]
distributed_chunks = []
for chunk in chunks:
segments = encode_chunk(chunk)
distributed_chunks.append(segments)
for i, chunk_segs in enumerate(distributed_chunks):
print(f"\n チャンク{i+1}:")
for j, seg in enumerate(chunk_segs):
print(f" ノード{j}: {seg}")
def recover_chunk(pieces):
combined = b''.join(pieces)
return rsc.decode(combined)
recovered_encrypted = b''
for chunk_segs in distributed_chunks:
selected_pieces = chunk_segs[:DATA_SEGMENTS]
recovered = recover_chunk(selected_pieces)
recovered_encrypted += recovered
decrypted_data = cipher.decrypt(recoved_encrypted)
print(f"\n復元された平文: {decrypted_data}")
$ python3 storj.py
元データ: b’StorjTestData1234567890!ThisIsAChunkTestFile!!’
暗号化データ: b’gAAAAABoLw7a8YpRJbYfA1bt6JOd9Rn28BVtmziV9-qXo9pWs41Or5LN8J0J3UKgAB7uTmpXjkHgTiEv_Dn4ajnfJATxU4lkoOS8xI67SmVeORdvPm6O6OEqGYBXfhQAGaBEtun2jHOw’
チャンク1:
ノード0: bytearray(b’gAAA’)
ノード1: bytearray(b’AABo’)
ノード2: bytearray(b’Lw7a’)
ノード3: bytearray(b’8YpR’)
ノード4: bytearray(b’JbYf’)
ノード5: bytearray(b’A1bt’)
ノード6: bytearray(b’6JOd’)
ノード7: bytearray(b’9Rn2′)
ノード8: bytearray(b”3\’\xf8\xd8″)
チャンク2:
ノード0: bytearray(b’8BVt’)
ノード1: bytearray(b’mziV’)
ノード2: bytearray(b’9-qX’)
ノード3: bytearray(b’o9pW’)
ノード4: bytearray(b’s41O’)
ノード5: bytearray(b’r5LN’)
ノード6: bytearray(b’8J0J’)
ノード7: bytearray(b’3UKg’)
ノード8: bytearray(b’\x1b\xe3=\xc7′)
チャンク3:
ノード0: bytearray(b’AB7u’)
ノード1: bytearray(b’TmpX’)
ノード2: bytearray(b’jkHg’)
ノード3: bytearray(b’TiEv’)
ノード4: bytearray(b’_Dn4′)
ノード5: bytearray(b’ajnf’)
ノード6: bytearray(b’JATx’)
ノード7: bytearray(b’U4lk’)
ノード8: bytearray(b’t\x915\xa3′)
チャンク4:
ノード0: bytearray(b’oOS8′)
ノード1: bytearray(b’xI67′)
ノード2: bytearray(b’SmVe’)
ノード3: bytearray(b’ORdv’)
ノード4: bytearray(b’Pm6O’)
ノード5: bytearray(b’6OEq’)
ノード6: bytearray(b’GYBX’)
ノード7: bytearray(b’fhQA’)
ノード8: bytearray(b’e\x02al’)
チャンク5:
ノード0: bytearray(b’Ga’)
ノード1: bytearray(b’BE’)
ノード2: bytearray(b’tu’)
ノード3: bytearray(b’n2′)
ノード4: bytearray(b’jH’)
ノード5: bytearray(b’Ow’)
ノード6: bytearray(b’\x00\xea’)
ノード7: bytearray(b’\x8b\x07′)
【Blockchain】siaをpythonで実装する
データをchunkして、encodeして、セグメントに分割して、nodeに保存する
import math
from reedsolo import RSCodec
import random
SEGMENT_SIZE = 8
DATA_SEGMENTS = 4
TOTAL_SEGMENTS = 6
CHUNK_SIZE = SEGMENT_SIZE * DATA_SEGMENTS
rsc = RSCodec(TOTAL_SEGMENTS - DATA_SEGMENTS)
def generate_fake_file(size=40):
return bytearray([random.randint(0, 255) for _ in range(size)])
def split_into_chunks(data, chunk_size):
return [data[i:i+chunk_size] for i in range(0, len(data), chunk_size)]
def encode_chunk(chunk):
segments = [chunk[i:i+SEGMENT_SIZE] for i in range(0, len(chunk), SEGMENT_SIZE)]
joined_data = b''.join(segments)
encoded = rsc.encode(joined_data)
seg_len = len(encoded) // TOTAL_SEGMENTS
encoded_segments = [encoded[i:i+seg_len] for i in range(0, len(encoded), seg_len)]
return encoded_segments
def distribute_segments(segments):
nodes = {}
for i, seg in enumerate(segments):
nodes[f"node_{i}"] = seg
return nodes
fake_file = generate_fake_file(40)
print(fake_file)
chunks = split_into_chunks(fake_file, CHUNK_SIZE)
for i, chunk in enumerate(chunks):
print(f"チャンク {i+1}: {chunk}")
encoded_segments = encode_chunk(chunk)
print(f" ↳ 符号化セグメント数: {len(encoded_segments)} ")
distributed = distribute_segments(encoded_segments)
for node, seg in distributed.items():
print(f" {node}に保存: {seg}")
print()
$ python3 sia.py
bytearray(b”Xz\xe12\x1a\xe7aq\xf3\’\x11\xcb\xa7\xf0\x0f*r\xd5Y4y#|\xb2\xe0\xeb\xb4\x14+\xedl\xe2\xf9\x1b\xe9s\x93\xc0\x94\xde”)
チャンク 1: bytearray(b”Xz\xe12\x1a\xe7aq\xf3\’\x11\xcb\xa7\xf0\x0f*r\xd5Y4y#|\xb2\xe0\xeb\xb4\x14+\xedl\xe2″)
↳ 符号化セグメント数: 7
node_0に保存: bytearray(b’Xz\xe12\x1a’)
node_1に保存: bytearray(b”\xe7aq\xf3\'”)
node_2に保存: bytearray(b’\x11\xcb\xa7\xf0\x0f’)
node_3に保存: bytearray(b’*r\xd5Y4′)
node_4に保存: bytearray(b’y#|\xb2\xe0′)
node_5に保存: bytearray(b’\xeb\xb4\x14+\xed’)
node_6に保存: bytearray(b’l\xe2q\xac’)
チャンク 2: bytearray(b’\xf9\x1b\xe9s\x93\xc0\x94\xde’)
↳ 符号化セグメント数: 10
node_0に保存: bytearray(b’\xf9′)
node_1に保存: bytearray(b’\x1b’)
node_2に保存: bytearray(b’\xe9′)
node_3に保存: bytearray(b’s’)
node_4に保存: bytearray(b’\x93′)
node_5に保存: bytearray(b’\xc0′)
node_6に保存: bytearray(b’\x94′)
node_7に保存: bytearray(b’\xde’)
node_8に保存: bytearray(b’\xb9′)
node_9に保存: bytearray(b’\xd8′)
C++のメモリの扱い
C言語はメモリ確保関数だったが、C++は命令で確保する
### メモリ確保/解放命令
– new
メモリを確保する命令
確保できない場合はstd::bad_allocを投げる
std::nothrowを指定すると、例外ではなくnullptrを返す
– delete
newで確保した領域を解放する命令
– delete[]
newで確保した領域を解放する命令
# include <memory>
int main() {
// 通常の確保
char* p = new char[100];
char* p2 = nullptr;
try {
p2 = new char[100];
} catch (const std::bad_alloc& e) {
}
char* p3 = new(std::nothrow) char[100];
if (p3 == nullptr) {
}
// 指定した領域からメモリを確保する
char buf[100];
char* p4 = new (buf) char[100];
int* n = new int;
int* n2 = new int();
int* n3 = new int(10);
delete n3;
delete n2;
delete n;
delete[] p3;
delete[] p2;
delete[] p;
}
#include <iostream>
int main() {
int* p = new int;
*p = 77;
std::cout << *p << std::endl;
delete p;
}
### 配列の確保
#include <iostream>
int main() {
int* arr = new int[5];
for (int i = 0; i < 5; ++i)
arr[i] = i * 10;
for (int i = 0; i < 5; ++i)
std::cout << arr[i] << " ";
delete[] arr;
return 0;
}
$ ./test
0 10 20 30 40
### スマートポインタ
#include <iostream>
#include <memory>
class Sample {
public:
void greet() {
std::cout << "Hello from Sample!\n";
}
};
int main() {
std::unique_ptr<Sample> ptr = std::make_unique<Sample>();
ptr->greet();
return 0;
}
C言語のメモリの扱い
### メモリ管理の概要
1. メモリ確保
2. メモリ解放
の順番で制御する
– メモリリーク
確保したメモリを不要になっても解放せずにいると、結果としてメモリ不足となって確保できなくなる
### メモリ確保・解放関数
– malloc
指定されたサイズのメモリを確保する
確保できない場合はNullを返す
– calloc
指定されたサイズのメモリブロックを確保し、確保した領域を0クリアする
確保できない場合はNullを返す
– realloc
確保済みのメモリを拡張する
確保できない場合はNullを返す
– free
malloc, calloc, reallocで確保した領域を解放する関数
# include <stdlib.h>
int main(void) {
printf("Practice C Memory Programming!! \n");
// 100 byteのメモリ確保
char* p = malloc(100);
if (p == NULL) {
// 確保できなかった時の処理
}
int* p2 = calloc(100, sizeof(int));
if (p2 == NULL){}
char* p3 = realloc(p, 200);
if (p3 == NULL) {
} else {
p = p3;
}
free(p2);
free(p);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Practice C Memory Programming!! \n");
int *p;
p = (int *)malloc(sizeof(int));
if (p == NULL) {
printf("メモリの確保に失敗しました\n");
return 1;
}
*p = 55;
printf("pが指す値: %d\n", *p);
free(p);
return 0;
}
$ ./test
Practice C Memory Programming!!
pが指す値: 55
配列の場合
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Practice C Memory Programming!! \n");
int *arr;
int n = 5;
arr = (int *)malloc(n * sizeof(int));
if (arr == NULL) {
printf("メモリの確保に失敗しました\n");
return 1;
}
for (int i = 0; i < n; i++){
arr[i] = i * 10;
}
for (int i = 0; i < n; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
free(arr);
return 0;
}
$ ./test
Practice C Memory Programming!!
arr[0] = 0
arr[1] = 10
arr[2] = 20
arr[3] = 30
arr[4] = 40
ipfsの利用
### ローカル環境でのipfs
$ echo “version 1 of my text” > mytextfile.txt
$ cat mytextfile.txt
version 1 of my text
$ ipfs cat QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy
version 1 of my text
これをipfsネットワークで実行したい
### ipfsに接続
# ipfs daemon
別のターミナルで以下を実行
# ipfs swarm peers |head
/ip4/103.253.72.2/tcp/4001/p2p/12D3KooWMGNgfvPVhUdzWfGifHMkVvJ991EQCCEWXTREc8CPHui7
/ip4/104.244.76.218/tcp/4001/p2p/12D3KooWMbUuHSEvy4KNnkW8H9m63zesuuvVNS25hTL1SQtRh835
/ip4/109.123.240.146/tcp/4001/p2p/12D3KooWPzJcDSFQrBSgrdPbSAwTX5x6aWKWAoAzuEj3NBb43iKD
/ip4/109.203.194.197/tcp/56881/p2p/12D3KooWMgRnDE2oPkd72ZVb3pw4Pww9F24nVfCPj18gB1ARhUCt
/ip4/112.25.240.107/tcp/4001/p2p/12D3KooWHkTtvW6qCR9yATp6g8EC6hHRZGEiybyLQqmsRwoJ7Ac2
/ip4/113.89.245.184/tcp/15088/p2p/12D3KooWD8U6239pcaHdYqrg175DwM9EvFxLMuWo5PjzHd7bLZ15
/ip4/115.204.117.91/tcp/35129/p2p/12D3KooWGknnwvTJwjzYHpXgYU5K6fF2P9d8wtT3zBYudwnA7XmZ
/ip4/117.26.88.117/tcp/51698/p2p/QmQGeMkzJmkWum4FQwxvx6QPTvuNTsGoXBXeCxsWMrHg31
/ip4/136.243.46.54/tcp/4001/p2p/12D3KooWMahkHusnsTbMGVnCyXmKyLyifD8VnpMiH4hKNn6wqPfb
/ip4/136.244.116.199/tcp/4001/p2p/12D3KooWCXC9dBZZsA6E2jJh8SoyGCsGbFSLQtBquthoQpqjgpKp
ubuntuにipfsのインストール
$ wget https://dist.ipfs.io/go-ipfs/v0.5.0/go-ipfs_v0.5.0_linux-arm64.tar.gz
$ tar xvzf go-ipfs_v0.5.0_linux-arm64.tar.gz
$ cd go-ipfs/
$ sudo ./install.sh
Moved ./ipfs to /usr/local/bin
$ ipfs version
ipfs version 0.5.0
$ ipfs init
initializing IPFS node at /home/vagrant/.ipfs
generating 2048-bit RSA keypair…done
peer identity: QmWKa24RSJMHNZNSWiB5FuUkLQFvkM7L8ZqhmUKaUbLAJF
to get started, enter:
ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
$ ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
Hello and Welcome to IPFS!
██╗██████╗ ███████╗███████╗
██║██╔══██╗██╔════╝██╔════╝
██║██████╔╝█████╗ ███████╗
██║██╔═══╝ ██╔══╝ ╚════██║
██║██║ ██║ ███████║
╚═╝╚═╝ ╚═╝ ╚══════╝
If you’re seeing this, you have successfully installed
IPFS and are now interfacing with the ipfs merkledag!
——————————————————-
| Warning: |
| This is alpha software. Use at your own discretion! |
| Much is missing or lacking polish. There are bugs. |
| Not yet secure. Read the security notes for more. |
——————————————————-
Check out some of the other files in this directory:
./about
./help
./quick-start <-- usage examples
./readme <-- this file
./security-notes
$ ls ~/.ipfs
blocks config datastore datastore_spec keystore version