TV WATCH

2001/09 20-31
Last Modified : 09/26 02:22
Total Access :
Today Access :
Your Access : COOKIE_TIMES: deprecated in static mode.

2001/09/20 (Thu)

#1 [PC] ( ;T T) < Windows調整

ノートにプリインストールされているWindows98SEを なんとかつかえるようにしてみた。
まずセキュリティパッチをWindows Updateからいれる。 ついでに Windows Media Player も7.1にアップデートする。 そして IE6 をインストールする。
Windowsスピードアップ術 を参考にディスク使用とタスクスイッチを最適化。 さらに無駄なデスクトップアイコンを削除し4つまで減らす。
それから以下のアプリケーションをインストール。

あと WindowBlinds も試してみるがあまり使わないだろう。
これに IriaRarUtyホットゾヌ ( monazilla )なんか入れたらまさに厨房仕様だな。

#2 [PC] ( ^ ^) < cygwinでコンパイル。

cygwin が使えるのはいいんだけど、Linuxでよく使うコマンドがいくつか ないのでそれをインストールしてみた。
まずは lv をインストールした。 普通にコンパイルはうまくいくがデフォルトのアウトプットがSJISでない のでそれを変える。src/conf.cの中のDEFAULT_OUTPUT_CODING_SYSTEM定義 をISO_2022_JPからSHIFT_JISに変更すればOK。
w3m をインストール。基本的にconfigureスクリプトに対話で答えればOK (出力の文字コードではShift_JISを選ぶ)。 ちなみにXMakefileのINCLUDESに-I/usr/include/opensslを 追加すればMonstar設定でもコンパイルできる。 インストールディレクトリはXXMakefileにある(デフォルトは/usr/localになっている)。
けっこうすんなりいけたのでなんか sylpheed を入れたくなったな(やっぱりだめだった)。

2001/09/22 (Sat)

#1 [PC] ( ^ ^) < キャプチャカード購入!

玄人志向 の安いキャプチャカードBT878A-PCIを買った。 サウンドはモノラルだけど値段が安いのでまあOK。 空けてみると中味はPV951だった。 これって中の見えないバルク品だよな。
Linuxで十分使えてます。 zapping 最高。終了は遅いけど。
ほんとはDVDつきのCD-Rドライブを買いたかったけど、 まだまだ下がりそうなので待つことに。 リコーRW9200が1万円くらいになれば即買いか。

#2 [プログラミング] ( ^ ^) < ハッカー・プログラミング大全購入

念願の ハッカー・プログラミング大全 を買った。 ていねいに書かれていて読みやすい。
昨日、坂村健教授がセキュリティについて講義をしたけど eTRON というものを考えているらしい。 専用ハードウェアとそのためのネットワークシステム を作るようだ。これはなりすましや 盗聴ができないようなものでもあるらしい。

#3 [つれづれ] ( ^ ^) < 新しい部屋は湿度が低い

新しい部屋に引っ越して2週間がすぎ気づいたが、前にくらべて湿度が低い。 千葉にいたときは60%は必ずあったのだが、いまの東京の部屋は40%くらいだ。 これは旭川の家くらいの量かなあ。本には優しいかも。

2001/09/23 (Sun)

#1 [プログラミング] ( ^ ^) < mmapでファイル読み書き

読み込み

 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <stdio.h>

 int show_file(char* filename);
 
 int main(int argc, char* argv[])
 {
      int i;
      if (argc <= 1) {
           printf("usage: %s file1 file2 ...\n", argv[0]);
           exit(0);
      }
      for (i = 1; i < argc; i++) {
           int ret;
           ret = show_file(argv[i]);
           if (ret < 0) {
                perror(argv[i]);    
           }
      }
      return 0;
 }
 
 int show_file(char* filename)
 {
      FILE* out = stdout;
      int fd;
      off_t offset = 0;
      struct stat fs;
      char* fp;
      
      fd = open(filename, O_RDONLY);
      if (fd < 0) {
           return -1;
      }
      fstat(fd, &fs);
      fp = mmap(NULL, fs.st_size, PROT_READ, MAP_SHARED, fd, offset);
      if ((int) fp < 0) {
           close(fd);
           return -1;
      }
      fwrite(fp, sizeof(char), fs.st_size, out);
      munmap(fp, fs.st_size);
      close(fd);
      return 0;     
 }

書き込み

 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <stdio.h>
 #include <string.h>
 
 int write_file(char* filename, char* data);
 
 int main(int argc, char* argv[])
 {
      int ret;
      if (argc != 3) {
           printf("usage: %s file text", argv[0]);
           exit(0);
      }
      ret = write_file(argv[1], argv[2]);
      if (ret < 0) {
           perror(argv[1]);
      }
      return ret;
 }
 
 int write_file(char* filename, char* data)
 {
      int fd;
      off_t offset = 0;
      size_t size;
      char* fp;
      int ret;
      
      size = strlen(data);
      fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
      if (fd < 0) {
           return -1;
      }
      ret = ftruncate(fd, size);
      if (ret < 0) {
           close(fd);
           return -1;
      }
      
      fp = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
      if ((int) fp < 0) {
           close(fd);
           return -1;
      }
      
      memcpy(fp, data, size);
      ret = msync(fp, size, 0);
      munmap(fp, size);
      close(fd);
      if (ret < 0) {
           return -1;
      }
      
      return 0;     
 }

mmapでファイルに書き込むときはあらかじめ書き込めるだけの ファイルの領域をとる必要がある。

2001/09/24 (Mon)

#1 [プログラミング] ( ^ ^) < ソケットプログラミング

サーバ

 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "define.h"
 
 void process_connection(int cfd, int counter) ;
 int server_open(int port, int backlog);
 
 int main(int argc, char* argv[]) {
      int sfd;
      int connect_count = 3;
      int i;
      
      sfd = server_open(PORT, connect_count);
      if (sfd < 0) {
           perror("server");
           exit(1);
      }
      
      for (i = 0; i < connect_count; i++) {
           int cfd;
           struct sockaddr_in caddr;
           int len;
           
           len = sizeof(caddr);
           cfd = accept(sfd, (struct sockaddr*) &caddr, &len);
           if (cfd < 0) {
                perror("client");
                continue;
           }
           
           process_connection(cfd, i);
           
           shutdown(cfd, SHUT_RDWR);
           close(cfd);
      }
      
      close(sfd);
      return 0;
 }
 
 void process_connection(int cfd, int counter) 
 {
      char buf[BUFSIZE];
      int ret;
      
      ret = read(cfd, buf, BUFSIZE);
      buf[0] = '0' + counter;
      puts(buf);
      write(cfd, buf, BUFSIZE);
 } 
 
 int server_open(int port, int backlog)
 {
      int sfd;
      int optval;
      struct sockaddr_in saddr;
      int ret;
      
      sfd = socket(PF_INET, SOCK_STREAM, 0);
      if (sfd < 0) {
           return sfd;
      }
      
      optval = 1;
      setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
      
      memset((char*) &saddr, 0, sizeof(struct sockaddr_in));
      saddr.sin_family = AF_INET;
      saddr.sin_port = htons(port);
      saddr.sin_addr.s_addr = INADDR_ANY;
      
      ret = bind(sfd, (struct sockaddr*) &saddr, sizeof(saddr));
      if (ret < 0) {
           close(sfd);
           return ret;
      }
      
      ret = listen(sfd, backlog);
      if (ret < 0) {
           close(sfd);
           return ret;
      } 

      return sfd;
 }

listenのbacklogは待ち受けする数。setsockoptのSO_REUSEADDRを1にすることは 連続してこのプログラムを実行するのに必要な処理です。shutdownはストリームを 閉じるものです(man 2 shutdown)。
クライアント

 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <netdb.h>
 
 #include "define.h"
 
 int connect_server(char* host, int port) ;
 void process_connection(int cfd);
 
 int main(int argc, char* argv[]) {
      int cfd;
      
      cfd = connect_server(HOST, PORT);
      if (cfd < 0) {
           perror("connect");
           exit(1);
      }
      
      process_connection(cfd);
      
      shutdown(cfd, SHUT_RDWR);
      close(cfd);
      
      return 0;
 }

 void process_connection(int cfd) 
 {
      char buf[BUFSIZE];
      
      strcpy(buf, "X is counter");
      write(cfd, buf, BUFSIZE);    
      read(cfd, buf, BUFSIZE);
      puts(buf);
 } 
 
 int connect_server(char* host, int port)
 {
      int cfd;
      struct sockaddr_in caddr;
      struct hostent* hp;
      int ret;
 
      cfd = socket(PF_INET, SOCK_STREAM, 0);
      if (cfd < 0) {
           return -1;
      }
      
      memset((char*) &caddr, 0, sizeof(struct sockaddr_in));
      caddr.sin_family = AF_INET;
      caddr.sin_port = htons(port);
      hp = gethostbyname(host);
      memcpy(&caddr.sin_addr.s_addr, *hp->h_addr_list, hp->h_length);
      
      ret = connect(cfd, (struct sockaddr*) &caddr, sizeof(caddr));
      if (ret < 0) {
           close(cfd);
           return ret;
      }
      
      return cfd;
 }

クライアントはbindではなくconnectを使って接続します。 bindが自分のアドレスを指定するのに対し、connectは相手のアドレスを指定します。
共通ヘッダ

 #define PORT 9977
 #define HOST "localhost"
 #define BUFSIZE 1024

PORTやHOSTは引数で設定することができるようにするべきだろう。

2001/09/25 (Tue)

#1 [プログラミング] ( ^ ^) < pthread プログラミング1

データ渡しっぱなしでスレッド立ち上げ。 gccのオプションでは-lpthreadが必要。

 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #define THREAD_MAX (100)
 
 typedef struct {
      int var;
 } DetachObject;
 
 void* run(void* arg);
 DetachObject* newDetachObject(int i);
 void destoryDetachObject(DetachObject* obj);
 
 int main(int argc, char* argv[])
 {
      int i;
      
      for (i = 0; i < THREAD_MAX; i++) {
           pthread_t thread;
           pthread_attr_t attr;
           DetachObject* obj;
           obj = newDetachObject(i);
            
           pthread_attr_init(&attr);
           pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
           pthread_create(&thread, &attr, &run, obj);
      }
      
      puts("main exit");
      return 0;
 }
 
 DetachObject* newDetachObject(int i)
 {
      DetachObject* obj;
      obj =  malloc(sizeof(DetachObject));
      obj->var = i;
      return obj;
 }
 
 void destoryDetachObject(DetachObject* obj)
 {
      free(obj);
 }
 
 void* run(void* arg)
 {
      DetachObject* obj = arg;
      
      printf("thread %d: count=%d\n", (int) pthread_self(), obj->var);
      
      destoryDetachObject(obj);
      
      return NULL;
 }

「スレッドに渡すオブジェクト」と「スレッドで実行する関数」を定義 するというのが基本。DETACHはjoinしない(戻り値を使わない)スレッドに使う。

#2 [プログラミング] ( ^ ^) < pthread プログラミング2

mutexによる排他ロックを使った共有データの変更。

 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #define THREAD_MAX (100)
 
 typedef struct {
      int var;
      pthread_mutex_t mutex;
 } SharedObject;
 
 void* run(void* arg);
 SharedObject* newSharedObject(void);
 void destorySharedObject(SharedObject* obj);
 
 int main(int argc, char* argv[])
 {
      SharedObject* obj;
      pthread_t threads[THREAD_MAX];
      int i;
      
      obj = newSharedObject(); 
      
      for (i = 0; i < THREAD_MAX; i++) {
           pthread_create(&(threads[i]), NULL, &run, obj);
      }
      
      for (i = 0; i < THREAD_MAX; i++) {
           int ret;
           pthread_join(threads[i], (void**) &ret);
           printf("result %dth: id=%d result=%d\n", i, (int) threads[i], ret);
      }
      
      destorySharedObject(obj);
      puts("main exit");
       return 0;
 }
 
 SharedObject* newSharedObject(void)
 {
      SharedObject* obj;
      obj = malloc(sizeof(SharedObject));
      obj->var = 0;
      pthread_mutex_init(&(obj->mutex), NULL);
      return obj;
 }
 
 void destorySharedObject(SharedObject* obj)
 {
      pthread_mutex_destroy(&(obj->mutex));
      free(obj);
 }
 
 void* run(void* arg)
 {
      SharedObject* obj = arg;
      int val;
      int ret;
      
      ret = pthread_mutex_lock(&(obj->mutex));
      if (ret != 0) {
            return (void*) -1;
      }
     
      obj->var++;
      val = obj->var;
      printf("thread %d: val=%d\n", (int) pthread_self(), obj->var);
      
      ret = pthread_mutex_unlock(&(obj->mutex));
      if (ret != 0) {
           return (void*) -1;
      }
      
      return (void*) val;
 }

排他する単位ごとにmutexを使う。 排他する領域はなるべくちいさくするのがいい。

#3 [プログラミング] ( ^ ^) < pthread プログラミング3

waitと通知。タイムアウトを指定する場合は pthread_cond_timedwaitを、 複数スレッドのwaitに対し通知する場合は pthread_cond_broadcastを使えばいい。

 #include <unistd.h>
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 typedef struct {
      int wait_count;
      int counter;
      pthread_mutex_t mutex;
      pthread_cond_t cond;
 } NotifyObject;
 
 void* run_wait(void* arg);
 void* run_notify(void* arg);
 NotifyObject* newNotifyObject(int wait_count);
 void destoryNotifyObject(NotifyObject* obj);
 
 int main(int argc, char* argv[])
 {
      NotifyObject* obj;
      pthread_t wait_thread;
      int i;
      
      obj = newNotifyObject(100); 
      
      pthread_create(&wait_thread, NULL, &run_wait, obj);
      sleep(1);
     
      for (i = 0; i < obj->wait_count; i++) {
           pthread_t notify_thread;
           pthread_attr_t attr;
            
           pthread_attr_init(&attr);
           pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
           pthread_create(&notify_thread, &attr, &run_notify, obj);
      }
      
      pthread_join(wait_thread, NULL);
           
      destoryNotifyObject(obj);
      puts("main exit");
      return 0;
 }
 
 NotifyObject* newNotifyObject(int wait_count)
 {
      NotifyObject* obj;
      
      obj = malloc(sizeof(NotifyObject));
      obj->wait_count = wait_count;
      obj->counter = 0;
      pthread_mutex_init(&(obj->mutex), NULL);
      pthread_cond_init(&(obj->cond), NULL);
      return obj;
 }
 
 void destoryNotifyObject(NotifyObject* obj)
 {
      pthread_mutex_destroy(&(obj->mutex));
      pthread_cond_destroy(&(obj->cond));
      free(obj);
 }
 
 void* run_wait(void* arg)
 {
      NotifyObject* obj = arg;
      int i;
      int ret;
      
      ret = pthread_mutex_lock(&(obj->mutex));
      if (ret != 0) {
           return (void*) -1;
      }
      for (i = 0; i < obj->wait_count; i++) {
           while (obj->counter == 0) {
                ret = pthread_cond_wait(&(obj->cond), &(obj->mutex));
                if (ret != 0) {
                     pthread_mutex_unlock(&(obj->mutex));
                     return (void*) -1;
                }
           }
           
           obj->counter--;
           puts("consume");
      }
      pthread_mutex_unlock(&(obj->mutex));
      
      return NULL;
 }
 
 void* run_notify(void* arg)
 {
      NotifyObject* obj = arg;
      int ret;
      
      ret = pthread_mutex_lock(&(obj->mutex));
      if (ret != 0) {
            return (void*) -1;
      }
     
      obj->counter++;
      puts("supply");
      
      pthread_cond_signal(&(obj->cond));
      
      pthread_mutex_unlock(&(obj->mutex));
      return NULL;
 }

共有オブジェクトがリソース待ちをするプログラム。 つまりrun_waitはcounterが0になるまでへらし、run_notifyは counterを1増やす。
注意点はwaitするとき、通知するときは同じmutexでロックすること。

#4 [プログラミング] ( ;^ ^) < ANSI-C言語のめんどうな点

やはりANSI-Cプログラミングでいちばんめんどうなのはエラー処理だ。 つぎはブロック先頭でしかできない変数宣言。 クラスはなくてもいいから、この2つだけでも克服したISO-Cがいいなあやっぱり。
あとCがC++より楽なのはやはりvoid*か。キャストが要らないから。
つぎはglibにしようか、でもglibは大きいしなあ。。。 そのまえにzlib(もちろんgzreadとかgzwriteとか)にしようか。。。 うーん、getoptとかregexとかも抑えておきたい気もする。。。


for 5 day(s).

[最新] [先月] [今月] [来月] [一覧]

[URL List] [Dictionary]

[static,style:t-hermes,jconv:NKF,cache:on]
Powered by Tomsoft Diary System 1.2.3
Copyright(C) 2001 by ichiyama ryoichi <ichiyama@jc4.so-net.ne.jp>. All rights reserved.