mikan's technical note

仕事&趣味で実験した小技の備忘録です(Linux,windows,DOS等)

MENU

【IchigoLatte】基本操作

テキストエディタ起動
lash>vi
※終了(保存)は、ESC

・プログラムの実行
lash>ms .
※強制終了は、ESC

・プログラムの消去(注意しましょう)
lash>echo > .

※IchigoLatteの電源OFFでもプログラムは消えません


【IchigoLatte本体以外に必要なもの】

PS/2対応のUSBキーボード
f:id:myerss555:20170806225158j:plain


・コンポジット入力のあるモニター(amazonなら1,000円くらい~)
これは近所のカホパーツセンターで購入した4.3インチカラーモニター
DC6~36Vに対応
別途12V1Aアダプタも購入
f:id:myerss555:20170806230352j:plain
f:id:myerss555:20170806230549j:plain
モニターの中身(液晶保護シートをはがすために分解)
f:id:myerss555:20170806230417j:plain

・microUSB電源(充電器)※スマホ用等でOK

【C言語】マルチスレッドの排他処理

Win32API
CreateEvent()
SetEvent
CreateThread()
WaitForSingleObject()
WaitForMultipleObjects
を使用したマルチスレッド排他処理の動作確認です。

//
// 【スレッドで順次処理(順不同)】※Windows7で動作確認済
// (c) 2017 mikan
// ※使用にあたっては利用者の自己責任でお願いします。
// ※参考文献 Advaned Windows 改訂第4版 Jeffrey Richter
//

#include "stdafx.h"
#include "windows.h"

#define   MAX_RUN_THREAD_NUM    32        // 作成するスレッドの数

int       gCount;                         // カウンタ
int       gNumber[MAX_RUN_THREAD_NUM];    // スレッド番号
char      gName[256];                     // スレッド名
HANDLE    ghEvent;                        // イベントハンドル

// ---------- 状態表示 ----------
void print_status()
{
    int     i;

    printf("%s:", gName);
    for (i = 0; i < MAX_RUN_THREAD_NUM; i++) {
        printf("%2d,", gNumber[i]);
    }
    printf("count=%2d\n", gCount);
}

// ---------- スレッド ----------
int Thread(PVOID pvParam)
{
    int     *n;

    // イベントシグナル待ち(30秒でタイムアウト)
    DWORD dw = WaitForSingleObject(ghEvent, 30 * 1000);
    if (dw == WAIT_FAILED || dw == WAIT_TIMEOUT) {
        return -1;
    }

    n = (int*)(pvParam);
    gNumber[gCount] = *n;
    gCount++;
    sprintf(gName, "Thread%02d", *n);

    // 状態表示
    print_status();

    //Sleep(200);    // debug用

    // イベントシグナル
    SetEvent(ghEvent);

    return 0;
}

// ---------- 親スレッド ----------
int ThreadCtrl()
{
    int     x[MAX_RUN_THREAD_NUM];
    int     i;
    DWORD   dwThreadId[MAX_RUN_THREAD_NUM];
    HANDLE  hThread[MAX_RUN_THREAD_NUM];

    // 初期化
    gCount = 0;
    memset(gNumber, 0x00, sizeof(gNumber));
    memset(gName, 0x00, sizeof(gName));
    memset(hThread, 0x00, sizeof(hThread));
    for (i = 0; i < MAX_RUN_THREAD_NUM; i++) {
        x[i] = i+1;
    }

    // 自動リセットイベント作成(いずれかのスレッド1つだけが、シグナルを検出)
    ghEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    // 手動リセットイベント作成(全てのスレッドが、同時にシグナルを検出)
    // ghEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    // スレッド作成
    for(i=0; i<MAX_RUN_THREAD_NUM; i++) {
        hThread[i] = CreateThread(
                         NULL,
                         0,
                         (PTHREAD_START_ROUTINE)Thread,
                         (PVOID)&x[i],
                         0,
                         &dwThreadId[i]);
    }

    // イベントシグナル
    SetEvent(ghEvent);

    // 全スレッド終了待ち
    DWORD dw = WaitForMultipleObjects(
                   MAX_RUN_THREAD_NUM,
                   hThread,
                   TRUE,
                   50 * 1000); // 50秒でタイムアウト

    // スレッドハンドルクローズ
    for (i = 0; i < MAX_RUN_THREAD_NUM; i++) {
        CloseHandle(hThread[i]);
    }

    if (dw == WAIT_FAILED || dw == WAIT_TIMEOUT) {
        return -1;
    }

    return 0;
}

// ---------- メイン ----------
void main()
{
    int     x;
    HANDLE  hThreadCtrl;
    DWORD   dwThreadCtrlId;
    DWORD   dwStart;
    
    dwStart = GetTickCount();

    printf("開始\n");

    // 親スレッド作成
    hThreadCtrl = CreateThread(
                      NULL,
                      0,
                      (PTHREAD_START_ROUTINE)ThreadCtrl,
                      (PVOID)&x,
                      0,
                      &dwThreadCtrlId);

    // 親スレッドの終了待ち(60秒でタイムアウト)
    DWORD dw = WaitForSingleObject(hThreadCtrl, 60 * 1000);

    // 親スレッドハンドルクローズ
    CloseHandle(hThreadCtrl);

    printf("終了\n");
    printf("経過時間=%d ms\n", GetTickCount() - dwStart);

    if (dw == WAIT_FAILED || dw == WAIT_TIMEOUT) {
        ;
    }

    return;
}

【実行結果】
※本PGでは各スレッドの起動順序はOSまかせとなります
f:id:myerss555:20170709051413j:plain

【手動リセットイベントで全スレッドを同時実行した結果】
※カウンタを正しくインクリメント出来ない可能性あり
f:id:myerss555:20170709052211j:plain

【C言語】VisualStudio 2015 VC++ 「strcpy()」 コンパイルエラー回避方法

ちょっとお試しでコーディングしたところこんなエラーが出ました。

C4996
'strcpy':
This function or variable may be unsafe.
Consider using strcpy_s instead.
To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

strcpyは使うなってことみたいですけどそうも言ってられないので対応策を。
(最終的な実行環境は WindowsNT4.0/Windows95, Visual C++ 4.0 なので・・・)

stdafx.h に1行追加することでコンパイルが通ります。
----------------------------------------
#pragma once

// ↓この1行を追加
#define _CRT_SECURE_NO_WARNINGS

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>
----------------------------------------