質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

VMware

VMwareとは、 ハードウェアで動作するOS上で仮想マシンを作成、実行するソフトウェアです。 Windows上でUNIX系OSを動作させたり、他のOS上で別の仮想OSを動作することが可能です。

Q&A

3回答

3138閲覧

WorkerThreadが2個目以降のキューを実行しません。

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

VMware

VMwareとは、 ハードウェアで動作するOS上で仮想マシンを作成、実行するソフトウェアです。 Windows上でUNIX系OSを動作させたり、他のOS上で別の仮想OSを動作することが可能です。

0グッド

0クリップ

投稿2017/06/09 01:41

WorkerThreadを用いたプログラムを作成しております。

概要

  • リストコマンドラインに入力された数字によって動作を変更し、

サブスレッドで入力され次第随時実行していきます。

  • キューには連結リストを使用しています。

環境
VMware 7.1.4 build-3848939
Unbuntu Linux

C言語

1#define _CRT_SECURE_NO_WARNINGS 2 3#include "stdlib.h" 4#include "stdio.h" 5#include "pthread.h" 6#include "CheckFile.h" 7#include "Integration.h" 8#include "Analysis.h" 9#include "AddList.h" 10#include "freeListPointer.h" 11#include "define.h" 12 13typedef struct Queue 14{ 15 int action; 16 struct Queue *next; 17 struct Queue *prev; 18}Queue; 19 20pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 21pthread_cond_t MainCond; 22pthread_mutex_t EventMutex; 23 24 25 26void *SubThread(void *p_arg); 27 28//Global Variable for End SubThread. 29int SubThreadEnd = 0; 30 31//Global Variable for count queue number. 32int count = 0; 33 34//Global Pointer Valiable for keep head pointer of queue. 35Queue *head = NULL; 36 37//Global Variable for end programs. 38int EndCount = 0; 39 40Queue *Enqueue(int action, Queue *p) 41{ 42 43 pthread_mutex_lock(&EventMutex); 44 Queue *ptr = (Queue *)malloc(sizeof(Queue)); 45 46 if(NULL == ptr) 47 { 48 printf("Could not get memory area.\n"); 49 } 50 51 if(p == NULL) 52 { 53 head = ptr; 54 ptr->action = action; 55 ptr->prev = NULL; 56 ptr->next = NULL; 57 pthread_mutex_unlock(&EventMutex); 58 return ptr; 59 } 60 61 ptr->action = action; 62 p->next = ptr; 63 ptr->prev = p; 64 ptr->next = NULL; 65 66 count++; 67 68 pthread_mutex_unlock(&EventMutex); 69 return ptr; 70 71} 72void Action(int action) 73{ 74 if(action == 1) 75 { 76 } 77 if(action == 2) 78 { 79 } 80 if(action == 3) 81 { 82 } 83//処理は省きます。 84 85void *SubThread(void *p_arg) 86{ 87 int loop = 0; 88 89 90 printf("SubThread - Starting.\n"); 91 92 while(1) 93 { 94 while(NULL != head) 95 { 96 pthread_mutex_lock(&EventMutex); 97 98 //Dequeue by excuting the function. 99 Action(head->action); 100 head = head->next; 101 102 pthread_mutex_unlock(&EventMutex); 103 pthread_cond_signal(&MainCond); 104 } 105 106 } 107} 108 109void main() 110{ 111 pthread_t th; 112 int action = 0; 113 Queue *p = NULL; 114 115 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 116 117 pthread_create(&th,NULL,SubThread,NULL); 118 119 pthread_cond_init(&MainCond, NULL); 120 pthread_mutex_init(&mutex, NULL); 121 122 while(1) 123 { 124 125 printf("Select the action.\n"); 126 printf("(1).Loading file.\n"); 127 printf("(2).Select analysis method.\n"); 128 printf("(3).Exit programs.\n"); 129 130 scanf("%d",&action); 131 132 p = Enqueue(action,p); 133 134 pthread_cond_wait(&MainCond,&mutex); 135 136 if(EndCount != 0) 137 { 138 break; 139 } 140 141 } 142 printf("Exit program.\n"); 143}

実行後、1回目の入力では、正常にサブスレッドが機能していることが確認されたのですが、
2回目以降、main関数でコマンドラインより入力を行うとEnqueueを実行し終わったところで
プログラムがとまってしまいます。(エラーなどによる動作停止ではなく、メインでwaitして
いるのにサブスレッドが動きません。)

なぜサブスレッドは無限ループにしているにもかかわらずとまってしまっているのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

Harahiraさんの指摘が正しいと思います。その背景は、結構自明に見えるheadの扱いかたの計画が緩いのではないかと思います。Enqueueの方も、もう少し簡単になります。

Queue *Enqueue(int action, Queue *p) { pthread_mutex_lock(&EventMutex); Queue *ptr = (Queue *)malloc(sizeof(Queue)); if(p == NULL) p = head ; p->next = ptr; ptr->action = action; ptr->prev = p; ptr->next = NULL; count++; pthread_mutex_unlock(&EventMutex); return ptr; }

たぶんheadの値は一度決めたら変更してはいけないのではないかと思います。
使用済のキューを捨てるなら、free の必要があります。
効率的にthreadするなら、

  1. quequeの管理は一か所に集める。queを足す関数、使う関数だけにqueueの扱いを任せる。
  2. mallocでqueueを足すときに、1つづつではなくて、100個くらいpoolしておいて、queueを数珠つなぎにする処理をactionの処理と並列実行するようにする。

みたいなふうに考えたほうがいいです。

投稿2018/06/07 15:13

gm300

総合スコア580

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

pthread関連で色々と問題があるとは思いますが、このプログラムが動かない原因はそこではありません。
一度、SubThread内のループを通るとheadがNULLとなり、以降、NULL以外の値になることがないために、SubThread内の処理が実行されません。
pthread関連の見直しと共に、キューの扱いについても、考え直した方がよいと思います。

投稿2017/06/09 04:19

Harahira

総合スコア243

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

条件変数(pthread_cond_t)の使い方を誤っています。

  • メインスレッド→サブスレッドに通知する設計ですから、メインスレッド側がSignal、サブスレッド側がWaitする構造になるべきです。
  • pthread_cond_wait(cv,m)関数は、第2引数に指定したミューテックスのロックを保持した状態、つまりpthread_mutex_lock(m)pthread_mutex_unlock(m)区間の中で呼び出す必要があります。

手前味噌ですが 条件変数 Step-by-Step入門 にて正しい使い方を解説しています。ご参考までに。

投稿2017/06/09 02:11

編集2017/06/09 02:15
yohhoy

総合スコア6189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/09 02:43 編集

回答ありがとうございます。 lock→wait→signalでunlockという流れだったのですね。 使い方を誤っていました。 省いてしまっているのですが、Action関数内の処理にファイル名を入力する処理を設けています。 yohhoyさんがおっしゃったように、SubThread側でwaitさせ、main関数でsignalを出すと言う方法で行うと、main関数がsignalでlock/waitしているSubThread起こした際、ファイル名の入力を行います。するとmain関数でのwhile内のscanfが当然同時に処理されているわけですが、ファイル入力の際、(サブスレッドが終了するまで)メインスレッドをとめる方法はありますでしょうか。 main 数字入力 subthread 受け取って処理(ここでファイル名の入力も行います) main数字入力 subthread 受け取って処理(ここでファイル名の入力も行います) ... というように処理をしたいのです。 scanfのあとlock・waitさせ、SubThreadが終了すればmainにsignalを返すという方法を思いついたのですが、signalを打ち合っていてわけが分からなくなるといわれてしまいました。 この方法は良くないのでしょうか。 また違った解決策があればご教授願いたいです。 サイト拝見しました。 しかし、C++を触ったことが無いので、説明をコードで落とし込むことがあまり出来ませんでした・・ せっかく記載してくださったのに申し訳ありません・・・
yohhoy

2017/06/09 02:50 編集

(断言はできませんが)signal/waitの仕組みを勘違いされているようにも思えます... また、メインスレッド/サブスレッドの両方が同種I/O(ここではキー入力)を待ち受ける構造にも違和感があります。 pthreadで説明している良い資料はあまり見つからない気がしますが、書籍「Pthreadsプログラミング」 https://www.oreilly.co.jp/books/4900900664/ は参考になるかと思います。(というより他に良い情報源を知りません)
yohhoy

2018/06/08 04:16

(codezineは非会員でも読めると嬉しいんですけどねー; ここで言っても詮無いお話)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問