Streamlining Multi-Party C++ Program Execution: A Comprehensive Automation Guide

Automating Multi-Party Communication for a C++ Program

This tutorial will guide you through automating the execution of a C++ program requiring three parties to communicate. We’ll cover multiple methods to achieve this, with a detailed description for using Python with libtmux.

Prerequisites

  • Basic knowledge of command line and scripting
  • Required tools installed (varies by method)

Methods to Automate Multi-Party Communication

  1. Using Bash Script with tmux
  2. Using Makefile
  3. Using Python with libtmux (detailed)
  4. Using Docker

Method 1: Using Bash Script with tmux

This method leverages tmux commands directly in a shell script.

Create a bash script file, e.g., run_experiments.sh:

#!/bin/bash

# Define the session name
SESSION_NAME="MultiPartySession"

# Start a new tmux session and run the server
tmux new-session -d -s $SESSION_NAME -n server "./your_program server"

# Create a new window and run the third_party
tmux new-window -t $SESSION_NAME -n third_party "./your_program third_party"

# Allow some time for the server and third_party to start
sleep 5

# Create a new window and run the client_access
tmux new-window -t $SESSION_NAME -n client_access "./your_program client_access"

# Wait for the client to finish (adjust the sleep time based on expected duration)
sleep 60

# Terminate the server and third_party processes
pkill -f "./your_program server"
pkill -f "./your_program third_party"

# Kill the tmux session
tmux kill-session -t $SESSION_NAME

Make the script executable and run it:

chmod +x run_experiments.sh
./run_experiments.sh

Method 2: Using Makefile

Using a Makefile is a structured approach often used for compiling and running programs with specific parameters.

Create a Makefile:

TMUX_SESSION = MultiPartySession
CLIENT_ACCESS_TIME = 60

.PHONY: run
run:
	tmux new-session -d -s $(TMUX_SESSION) -n server "./your_program server"
	sleep 5
	tmux new-window -t $(TMUX_SESSION) -n third_party "./your_program third_party"
	sleep 5
	tmux new-window -t $(TMUX_SESSION) -n client_access "./your_program client_access"
	sleep $(CLIENT_ACCESS_TIME)
	$(MAKE) terminate

.PHONY: terminate
terminate:
	pkill -f "./your_program server"
	pkill -f "./your_program third_party"
	tmux kill-session -t $(TMUX_SESSION)

Run the Makefile:

make run

Method 3: Using Python with libtmux (Detailed)

This method uses the libtmux library to manage tmux sessions programmatically.

Install Required Tools

Install tmux:

For Ubuntu/Debian:
sudo apt-get update
sudo apt-get install tmux
For CentOS/RHEL:
sudo yum install tmux
For macOS:
brew install tmux

Install libtmux Python Library:

pip install libtmux

Create the Python Script

Create a new Python script file, e.g., run_experiments.py, and copy the following code into it:

import os
import subprocess
import time
import libtmux

def find_and_kill_process_using_port(port):
    try:
        pids = subprocess.check_output(['lsof', '-t', '-i:{}'.format(port)], text=True).strip().split()
        for pid in pids:
            if pid:
                print(f"Port {port} is being used by PID {pid}, attempting to kill.")
                subprocess.check_call(['kill', '-9', pid])  # Forcefully terminating the process
                print(f"Successfully killed process {pid}")
    except subprocess.CalledProcessError as e:
        print(f"No process is using port {port} or failed to kill process: {e}")

def main():
    tmux_server = libtmux.Server()
    session_name = "MultiPartySession"

    # Example ports to be cleared before starting
    ports = [8283, 8288]

    for port in ports:
        find_and_kill_process_using_port(port)

    # Example Z and R values for demonstration purposes
    rest_z = [14, 18, 22]
    compileAndMove = {
        'Z': [14, 18, 22, 26],
        'R': [115, 127, 139, 151],
        'p_stash': 8283,
        'p_tp': 8288
    }

    for z, r in zip(compileAndMove['Z'], compileAndMove['R']):
        if z not in rest_z:
            continue

        print(f"Running experiment with Z={z} and R={r}")

        # Construct the common command path
        commonCommandPath = f"./your_program_Z_{z}_R_{r}"

        # Create a new tmux session and windows for server, third_party, and client
        session = tmux_server.new_session(session_name=session_name, kill_session=True, detach=True)

        # Start the server in the first window
        server_window = session.new_window(window_name="server", attach=False)
        server_pane = server_window.active_pane
        server_pane.send_keys(f"{commonCommandPath} server", enter=True)
        print(f"Started server for Z={z} and R={r}")

        # Start the third_party in the second window
        third_party_window = session.new_window(window_name="third_party", attach=False)
        third_party_pane = third_party_window.active_pane
        third_party_pane.send_keys(f"{commonCommandPath} third_party", enter=True)
        print(f"Started third_party for Z={z} and R={r}")

        # Allow some time for server and third_party to start
        time.sleep(5)

        # Start the client in the third window
        client_window = session.new_window(window_name="client_access", attach=False)
        client_pane = client_window.active_pane
        client_pane.send_keys(f"{commonCommandPath} client_access", enter=True)
        print(f"Started client_access for Z={z} and R={r}")

        # Wait for the client to finish by continuously checking its output
        while True:
            time.sleep(1)
            output = client_pane.capture_pane()
            if not output or all(line.strip() == "" for line in output):
                break

        # Log output from each pane (optional, for debugging)
        server_output = server_pane.capture_pane()
        third_party_output = third_party_pane.capture_pane()
        client_output = client_pane.capture_pane()

        print(f"Server output for Z={z} and R={r}:\n{''.join(server_output)}")
        print(f"Third party output for Z={z} and R={r}:\n{''.join(third_party_output)}")
        print(f"Client output for Z={z} and R={r}:\n{''.join(client_output)}")

        # Terminate the server and third_party processes
        server_pane.cmd('send-keys', 'C-c')
        third_party_pane.cmd('send-keys', 'C-c')
        print(f"Terminated server and third_party for Z={z} and R={r}")

        # Ensure all processes have stopped
        time.sleep(1)

        # Close the tmux session
        session.kill_session()
        print(f"Closed tmux session for Z={z} and R={r}")

        # Delay before starting the next iteration, if necessary
        time.sleep(1)

    print("All tasks completed.")

if __name__ == "__main__":
    main()

Run the Python Script

Make the script executable (optional but recommended):

chmod +x run_experiments.py

Run the script:

python run_experiments.py

Verify the Execution

  1. Monitor the Output: Check the output of the script to see detailed logging messages.
  2. Attach to the tmux Session: Use tmux attach-session -t MultiPartySession to attach to the tmux session and see the output of each command in real-time.
  3. Check Running Processes: Use ps aux | grep your_program to check if the processes are running.

Troubleshooting

  1. Ports Already in Use: Ensure the ports used by your processes are free. The script attempts to kill any processes using specific ports at the start.
  2. Processes Not Starting: Check the command paths and ensure the executable is in the correct directory. Verify the output of each pane for error messages.
  3. Script Errors: Read the error messages in the output and make necessary adjustments. The provided script logs detailed output for debugging purposes.

Conclusion

This tutorial demonstrated multiple methods to automate the execution of a multi-party C++ program. The detailed method using Python and libtmux offers a flexible and programmatic approach to managing tmux sessions and windows. Choose the method that best fits your requirements and environment.

For further customization and debugging, refer to the libtmux documentation and adjust the script as needed.

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值