Open MPI logo

Open MPI User's Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Open MPI User's mailing list

Subject: Re: [OMPI users] How to create multi-thread parallel program using thread-safe send and recv?
From: guosong (guosong1079_at_[hidden])
Date: 2009-09-22 11:52:09


Thanks for responding. I used a linux cluster. I think I would like to create a model that is multithreaded and each thread can make MPI calls. I attached test code as follow. It has two pthreads and there are MPI calls in both of those two threads. In the main function, there are also MPI calls. Should I use a full multithreading? Thanks again.

 

 

#include <iostream>
#include <pthread.h>
#include <fstream>
#include <sstream>
#include <string.h>
#include "mpi.h"
using namespace std;

pthread_mutex_t _dealmutex;
pthread_mutex_t _dealmutex1;
pthread_mutex_t _dealmutex2;

void* backID(void* arg)
{
 int myid;
 pthread_mutex_init(&_dealmutex1, NULL);
 stringstream RANK;
 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
 RANK << myid;
 cout << myid << " create background ID" << endl;
 int v;
 MPI_Status status;
 MPI_Request requ1, requ2;
 int m;
 int x, y;
 int count = 0;
 string filename("f_");
 filename += RANK.str();
 filename += "_backID.txt";
 fstream fout(filename.c_str(), ios::out);
 if(!fout)
 {
  cout << "can not create the file " << filename << endl;
  fout.close();
  exit(1);
 }
 while(true)
 {
  MPI_Irecv(&m, 1, MPI_INT, MPI_ANY_SOURCE, 222, MPI_COMM_WORLD, &requ1);
  MPI_Wait(&requ1, &status);
  //fout << myid << " recv from " << status.MPI_SOURCE << " m = " << m << " with tag 222" << endl;
  //pthread_mutex_lock(&_dealmutex1);
  //cout << "BACKID_REV:" << myid << " recv from " << status.MPI_SOURCE << " m = " << m << " with tag 222" << endl;
  fout << "BACKID_REV:" << myid << " recv from " << status.MPI_SOURCE << " m = " << m << " with tag 222" << endl;
  //fflush(stdout);
  fout.flush();

  //pthread_mutex_unlock(&_dealmutex1);
  //m++;
  MPI_Send(&m, 1, MPI_INT, status.MPI_SOURCE, 333, MPI_COMM_WORLD);
  //MPI_Isend(&m, 1, MPI_INT, status.MPI_SOURCE, 333, MPI_COMM_WORLD, &requ2);
  //pthread_mutex_lock(&_dealmutex1);
  //fout << myid << " replies " << status.MPI_SOURCE << " m = " << m << endl;
  //cout << "BACKID_SEND:" << myid << " replies " << status.MPI_SOURCE << " m = " << m << endl;
  fout << "BACKID_SEND:" << myid << " replies " << status.MPI_SOURCE << " m = " << m << endl;
  //fflush(stdout);
  fout.flush();
  //pthread_mutex_unlock(&_dealmutex);
  count++;
  //pthread_mutex_unlock(&_dealmutex1);
  if(count == 50)
  {
   fout << "*******backID FINISHED IN " << myid << "********" << endl;
   fout.flush();
   fout.close();
   pthread_exit(NULL);
   return 0;
  }
 };
}

void* backRecv(void* arg)
{
 int myid;
 pthread_mutex_init(&_dealmutex2, NULL);
 stringstream RANK;
 MPI_Status status;
 MPI_Request requ2;
 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
 RANK << myid;
 cout << myid << " create background message recv" << endl;
 int x, y;
 //char c;
 int m;
 int count = 0;
 string filename("f_");
 filename += RANK.str();
 filename += "_backRecv.txt";
 fstream fout(filename.c_str(), ios::out);
 if(!fout)
 {
  cout << "can not create the file " << filename << endl;
  fout.close();
  exit(1);
 }

 while(true)
 {
  MPI_Irecv(&m, 1, MPI_INT, MPI_ANY_SOURCE, 333, MPI_COMM_WORLD, &requ2);
  MPI_Wait(&requ2, &status);
  //pthread_mutex_lock(&_dealmutex2);
  fout << "BACKREV:" << myid << " recv from " << status.MPI_SOURCE << " m = " << m << " with tag 333" << endl;
  fout.flush();
  //cout << "BACKREV:" << myid << " recv from " << status.MPI_SOURCE << " m = " << m << " with tag 333" << endl;
  //fflush(stdout);
  //pthread_mutex_unlock(&_dealmutex);
  //pthread_mutex_lock(&_dealmutex);
  count++;
  //pthread_mutex_unlock(&_dealmutex2);
  if(count == 50)
  {
   fout << "*******backRecv FINISHED IN " << myid << "********" << endl;
   fout.flush();
   fout.close();
   pthread_exit(NULL);
   return 0;
  }
 };
}

int main(int argc, char **argv)
{
 int myid = 0;
 int nprocs = 0;
 pthread_t pt1 = 0;
    pthread_t pt2 = 0;;
 int pret1 = 0;
 int pret2 = 0;
 int i = 0, j = 0, t = 0;
 //MPI_Status status;
 MPI_Request requ1;
 MPI_Init(&argc,&argv);
   MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
   MPI_Comm_rank(MPI_COMM_WORLD,&myid);
 pthread_mutex_init(&_dealmutex, NULL);
 
 for(i=0; i<50; ++i)
 {
  t = (myid + 1) * i;
  MPI_Isend(&myid, 1, MPI_INT, (myid+1)%nprocs, 222, MPI_COMM_WORLD, &requ1);
  //MPI_Sendrecv(&t, 1, MPI_INT, (myid+1)%nprocs, 222, &j, 1, MPI_INT, (myid+1)%nprocs, 333, MPI_COMM_WORLD, &status);
  cout << "MAIN:" << myid << " sends to "<< (myid+1)%nprocs << " " << myid << endl;
  fflush(stdout);
 }
 pret1 = pthread_create(&pt1, NULL, backRecv, NULL);
 if(pret1 != 0)
    {
        cout << myid << "backRecv Thread Create Failed." << endl;
        exit(1);
    }
 pret2 = pthread_create(&pt2, NULL, backID, NULL);
 if(pret2 != 0)
 {
        cout << myid << "backID Thread Create Failed." << endl;
        exit(1);
 }
 //for(i=0; i<10; ++i)
 //{
 // c += i;
 // MPI_Send(&c, 1, MPI_CHAR, (myid+1)%nprocs, 111, MPI_COMM_WORLD);
 // cout << myid << " send " << (char)c << " to " << (myid+1)%nprocs << endl;
 //}
 pthread_join(pt2, NULL);
 cout << "*******************************THREAD 2 SUCESS!" << endl;
 pthread_join(pt1, NULL);
 cout << "*******************************THREAD 1 SUCESS!" << endl;
 MPI_Finalize();
 cout << "*******************************MAIN SUCESS!" << endl;
}

This peice of code works fine sometimes. But it can fail too and segmentation will occur. I will read the reference you point out. Thanks.
 

Date: Tue, 22 Sep 2009 08:43:11 -0700
From: Eugene.Loh_at_[hidden]
To: users_at_[hidden]
Subject: Re: [OMPI users] How to create multi-thread parallel program using thread-safe send and recv?

guosong wrote:

Hi all,
I would like to write a multi-thread parallel program. I used pthread. Basicly, I want to create two background threads besides the main thread(process). For example, if I use "-np 4", the program should have 4 main processes on four processors and two background threads for each main process. So there should be 8 threads totally.Wouldn't there be 4 main threads and 8 "slave" threads for a total of 12 threads? Anyhow, doesn't matter.

I'm not sure where you're starting, but you should at least have a basic understanding of the different sorts of multithreaded programming models in MPI. One is that each process is single threaded. Another is the processes are multithreaded, but only the main thread makes MPI calls. Another is multithreaded, but only one MPI call at a time. Finally, there can be full multithreading. You have to decide which of these programming models you want and which is supported by your MPI (or, if OMPI, how OMPI was built).

For more information, try the MPI_Init_thread() man page or
http://www.mpi-forum.org./docs/mpi21-report.pdf ... see Section 12.4 on "MPI and Threads".

I wrote a test program and it worked unpredictable. Sometimes I got the result I want, but sometimes the program got segmentation fault. I used MPI_Isend and MPI_Irecv for sending and recving. I do not know why? I attached the error message as follow:
 
[cheetah:29780] *** Process received signal ***
[cheetah:29780] Signal: Segmentation fault (11)
[cheetah:29780] Signal code: Address not mapped (1)
[cheetah:29780] Failing at address: 0x10
[cheetah:29779] *** Process received signal ***
[cheetah:29779] Signal: Segmentation fault (11)
[cheetah:29779] Signal code: Address not mapped (1)
[cheetah:29779] Failing at address: 0x10
[cheetah:29780] [ 0] /lib64/libpthread.so.0 [0x334b00de70]
[cheetah:29780] [ 1] /act/openmpi/gnu/lib/openmpi/mca_btl_sm.so [0x2b90e1227940]
[cheetah:29780] [ 2] /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so [0x2b90e05d61ca]
[cheetah:29780] [ 3] /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so [0x2b90e05cac86]
[cheetah:29780] [ 4] /act/openmpi/gnu/lib/libmpi.so.0(PMPI_Send+0x13d) [0x2b90dde7271d]
[cheetah:29780] [ 5] pt_muti(_Z6backIDPv+0x29b) [0x409929]
[cheetah:29780] [ 6] /lib64/libpthread.so.0 [0x334b0062f7]
[cheetah:29780] [ 7] /lib64/libc.so.6(clone+0x6d) [0x334! a4d1e3d]
[cheetah:29780] *** End of error message ***
[cheetah:29779] [ 0] /lib64/libpthread.so.0 [0x334b00de70]
[cheetah:29779] [ 1] /act/openmpi/gnu/lib/openmpi/mca_btl_sm.so [0x2b39785c0940]
[cheetah:29779] [ 2] /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so [0x2b397796f1ca]
[cheetah:29779] [ 3] /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so [0x2b3977963c86]
[cheetah:29779] [ 4] /act/openmpi/gnu/lib/libmpi.so.0(PMPI_Send+0x13d) [0x2b397520b71d]
[cheetah:29779] [ 5] pt_muti(_Z6backIDPv+0x29b) [0x409929]
[cheetah:29779] [ 6] /lib64/libpthread.so.0 [0x334b0062f7]
[cheetah:29779] [ 7] /lib64/libc.so.6(clone+0x6d) [0x334a4d1e3d]
[cheetah:29779] *** End of error message ***

 
I used gdb to "bt" the error and I got :
 Program terminated with signal 11, Segmentation fault.
#0 0x00002b90e1227940 in mca_btl_sm_alloc ()
   from /act/openmpi/gnu/lib/openmpi/mca_btl_sm.so
(gdb) bt
#0 0x00002b90e1227940 in mca_btl_sm_alloc ()
   from /act/openmpi/gnu/lib/openmpi/mca_btl_sm.so
#1 0x00002b90e05d61ca in mca_pml_ob1_send_request_start_copy ()
   from /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so
#2 0x00002b90e05cac86 in mca_pml_ob1_send ()
   from /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so
#3 0x00002b90dde7271d in PMPI_Send () from /act/openmpi/gnu/lib/libmpi.so.0
#4 0x0000000000409929 in backID (arg=0x0) at pt_muti.cpp:50
#5 0x000000334b0062f7 in start_thread () from /lib64/libpthread.so.0
#6 0x000000334a4d1e3d in clone () from /lib64/libc.so.6
So can anyone give me some suggestions or advice. Thanks very much.
_________________________________________________________________
´ò¹¤£¬ÕõÇ®£¬Âò·¿×Ó£¬¿ìÀ´MClubÒ»Æ𡱽ðÎݲؽ¿¡±£¡
http://club.msn.cn/?from=10
--_8cf70815-85b5-44f5-8859-ebdc96183bbd_
Content-Type: text/html; charset="gb2312"
Content-Transfer-Encoding: 8bit

<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
Thanks for responding. I&nbsp;used a&nbsp;linux cluster. I think I would like to create a model that is&nbsp;multithreaded and each&nbsp;thread can make MPI calls.&nbsp;I attached&nbsp;test code as follow. It&nbsp;has&nbsp;two pthreads and there are MPI calls&nbsp;in both of those two threads. In the main function, there&nbsp;are also&nbsp;MPI calls.&nbsp;Should I&nbsp;use a full multithreading? Thanks again.<BR>
&nbsp;<BR>
&nbsp;<BR>
#include &lt;iostream&gt;<BR>#include &lt;pthread.h&gt;<BR>#include &lt;fstream&gt;<BR>#include &lt;sstream&gt;<BR>#include &lt;string.h&gt;<BR>#include "mpi.h"<BR>using namespace std;<BR>
pthread_mutex_t _dealmutex;<BR>pthread_mutex_t _dealmutex1;<BR>pthread_mutex_t _dealmutex2;<BR>
void* backID(void* arg)<BR>{<BR>&nbsp;int myid;<BR>&nbsp;pthread_mutex_init(&amp;_dealmutex1, NULL);<BR>&nbsp;stringstream RANK;<BR>&nbsp;MPI_Comm_rank(MPI_COMM_WORLD, &amp;myid);<BR>&nbsp;RANK &lt;&lt; myid;<BR>&nbsp;cout &lt;&lt; myid &lt;&lt; " create background ID" &lt;&lt; endl;<BR>&nbsp;int v;<BR>&nbsp;MPI_Status status;<BR>&nbsp;MPI_Request&nbsp; requ1, requ2;<BR>&nbsp;int m;<BR>&nbsp;int x, y;<BR>&nbsp;int count = 0;<BR>&nbsp;string filename("f_");<BR>&nbsp;filename += RANK.str();<BR>&nbsp;filename += "_backID.txt";<BR>&nbsp;fstream fout(filename.c_str(), ios::out);<BR>&nbsp;if(!fout)<BR>&nbsp;{<BR>&nbsp;&nbsp;cout &lt;&lt; "can not create the file " &lt;&lt; filename &lt;&lt; endl;<BR>&nbsp;&nbsp;fout.close();<BR>&nbsp;&nbsp;exit(1);<BR>&nbsp;}<BR>&nbsp;while(true)<BR>&nbsp;{<BR>&nbsp;&nbsp;MPI_Irecv(&amp;m, 1, MPI_INT, MPI_ANY_SOURCE, 222, MPI_COMM_WORLD, &amp;requ1);<BR>&nbsp;&nbsp;MPI_Wait(&amp;requ1, &amp;status);<BR>&nbsp;&nbsp;//fout &lt;&lt; myid &lt;&lt; " recv from " &lt;&lt; status.MPI_SOU
RCE &lt;&lt; " m = " &lt;&lt; m &lt;&lt; " with tag 222" &lt;&lt; endl;<BR>&nbsp;&nbsp;//pthread_mutex_lock(&amp;_dealmutex1);<BR>&nbsp;&nbsp;//cout &lt;&lt; "BACKID_REV:" &lt;&lt; myid &lt;&lt; " recv from " &lt;&lt; status.MPI_SOURCE &lt;&lt; " m = " &lt;&lt; m &lt;&lt; " with tag 222" &lt;&lt; endl;<BR>&nbsp;&nbsp;fout &lt;&lt; "BACKID_REV:" &lt;&lt; myid &lt;&lt; " recv from " &lt;&lt; status.MPI_SOURCE &lt;&lt; " m = " &lt;&lt; m &lt;&lt; " with tag 222" &lt;&lt; endl;<BR>&nbsp;&nbsp;//fflush(stdout);<BR>&nbsp;&nbsp;fout.flush();<BR>
&nbsp;&nbsp;//pthread_mutex_unlock(&amp;_dealmutex1);<BR>&nbsp;&nbsp;//m++;<BR>&nbsp;&nbsp;MPI_Send(&amp;m, 1, MPI_INT, status.MPI_SOURCE, 333, MPI_COMM_WORLD);<BR>&nbsp;&nbsp;//MPI_Isend(&amp;m, 1, MPI_INT, status.MPI_SOURCE, 333, MPI_COMM_WORLD, &amp;requ2);<BR>&nbsp;&nbsp;//pthread_mutex_lock(&amp;_dealmutex1);<BR>&nbsp;&nbsp;//fout &lt;&lt; myid &lt;&lt; " replies " &lt;&lt; status.MPI_SOURCE &lt;&lt; " m = " &lt;&lt; m &lt;&lt; endl;<BR>&nbsp;&nbsp;//cout &lt;&lt; "BACKID_SEND:" &lt;&lt; myid &lt;&lt; " replies " &lt;&lt; status.MPI_SOURCE &lt;&lt; " m = " &lt;&lt; m &lt;&lt; endl;<BR>&nbsp;&nbsp;fout &lt;&lt; "BACKID_SEND:" &lt;&lt; myid &lt;&lt; " replies " &lt;&lt; status.MPI_SOURCE &lt;&lt; " m = " &lt;&lt; m &lt;&lt; endl;<BR>&nbsp;&nbsp;//fflush(stdout);<BR>&nbsp;&nbsp;fout.flush();<BR>&nbsp;&nbsp;//pthread_mutex_unlock(&amp;_dealmutex);<BR>&nbsp;&nbsp;count++;<BR>&nbsp;&nbsp;//pthread_mutex_unlock(&amp;_dealmutex1);<BR>&nbsp;&nbsp;if(count == 50)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;fout &lt;&lt
; "*******backID FINISHED IN " &lt;&lt; myid &lt;&lt; "********" &lt;&lt; endl;<BR>&nbsp;&nbsp;&nbsp;fout.flush();<BR>&nbsp;&nbsp;&nbsp;fout.close();<BR>&nbsp;&nbsp;&nbsp;pthread_exit(NULL);<BR>&nbsp;&nbsp;&nbsp;return 0;<BR>&nbsp;&nbsp;}<BR>&nbsp;};<BR>}<BR>
<BR>void* backRecv(void* arg)<BR>{<BR>&nbsp;int myid;<BR>&nbsp;pthread_mutex_init(&amp;_dealmutex2, NULL);<BR>&nbsp;stringstream RANK;<BR>&nbsp;MPI_Status status;<BR>&nbsp;MPI_Request&nbsp; requ2;<BR>&nbsp;MPI_Comm_rank(MPI_COMM_WORLD, &amp;myid);<BR>&nbsp;RANK &lt;&lt; myid;<BR>&nbsp;cout &lt;&lt; myid &lt;&lt; " create background message recv" &lt;&lt; endl;<BR>&nbsp;int x, y;<BR>&nbsp;//char c;<BR>&nbsp;int m;<BR>&nbsp;int count = 0;<BR>&nbsp;string filename("f_");<BR>&nbsp;filename += RANK.str();<BR>&nbsp;filename += "_backRecv.txt";<BR>&nbsp;fstream fout(filename.c_str(), ios::out);<BR>&nbsp;if(!fout)<BR>&nbsp;{<BR>&nbsp;&nbsp;cout &lt;&lt; "can not create the file " &lt;&lt; filename &lt;&lt; endl;<BR>&nbsp;&nbsp;fout.close();<BR>&nbsp;&nbsp;exit(1);<BR>&nbsp;}<BR>
&nbsp;while(true)<BR>&nbsp;{<BR>&nbsp;&nbsp;MPI_Irecv(&amp;m, 1, MPI_INT, MPI_ANY_SOURCE, 333, MPI_COMM_WORLD, &amp;requ2);<BR>&nbsp;&nbsp;MPI_Wait(&amp;requ2, &amp;status);&nbsp;&nbsp;<BR>&nbsp;&nbsp;//pthread_mutex_lock(&amp;_dealmutex2);<BR>&nbsp;&nbsp;fout &lt;&lt; "BACKREV:" &lt;&lt; myid &lt;&lt; " recv from " &lt;&lt; status.MPI_SOURCE &lt;&lt; " m = " &lt;&lt; m &lt;&lt; " with tag 333" &lt;&lt; endl;<BR>&nbsp;&nbsp;fout.flush();<BR>&nbsp;&nbsp;//cout &lt;&lt; "BACKREV:" &lt;&lt; myid &lt;&lt; " recv from " &lt;&lt; status.MPI_SOURCE &lt;&lt; " m = " &lt;&lt; m &lt;&lt; " with tag 333" &lt;&lt; endl;<BR>&nbsp;&nbsp;//fflush(stdout);<BR>&nbsp;&nbsp;//pthread_mutex_unlock(&amp;_dealmutex);<BR>&nbsp;&nbsp;//pthread_mutex_lock(&amp;_dealmutex);<BR>&nbsp;&nbsp;count++;<BR>&nbsp;&nbsp;//pthread_mutex_unlock(&amp;_dealmutex2);<BR>&nbsp;&nbsp;if(count == 50)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;fout &lt;&lt; "*******backRecv FINISHED IN " &lt;&lt; myid &lt;&lt; "********" &lt;&lt; endl;<BR>&nbsp;&nbsp;&nbsp
;fout.flush();<BR>&nbsp;&nbsp;&nbsp;fout.close();<BR>&nbsp;&nbsp;&nbsp;pthread_exit(NULL);<BR>&nbsp;&nbsp;&nbsp;return 0;<BR>&nbsp;&nbsp;}&nbsp;<BR>&nbsp;};<BR>}<BR>
int main(int argc, char **argv) <BR>{<BR>&nbsp;int myid = 0;<BR>&nbsp;int nprocs = 0;<BR>&nbsp;pthread_t pt1 = 0;<BR>&nbsp;&nbsp;&nbsp; pthread_t pt2 = 0;;<BR>&nbsp;int pret1 = 0;<BR>&nbsp;int pret2 = 0;<BR>&nbsp;int i = 0, j = 0, t = 0;<BR>&nbsp;//MPI_Status status;<BR>&nbsp;MPI_Request&nbsp; requ1;<BR>&nbsp;MPI_Init(&amp;argc,&amp;argv);<BR>&nbsp; &nbsp;MPI_Comm_size(MPI_COMM_WORLD,&amp;nprocs);<BR>&nbsp; &nbsp;MPI_Comm_rank(MPI_COMM_WORLD,&amp;myid); <BR>&nbsp;pthread_mutex_init(&amp;_dealmutex, NULL);<BR>&nbsp;<BR>&nbsp;for(i=0; i&lt;50; ++i)<BR>&nbsp;{<BR>&nbsp;&nbsp;t = (myid + 1) * i;<BR>&nbsp;&nbsp;MPI_Isend(&amp;myid, 1, MPI_INT, (myid+1)%nprocs, 222, MPI_COMM_WORLD, &amp;requ1);<BR>&nbsp;&nbsp;//MPI_Sendrecv(&amp;t, 1, MPI_INT, (myid+1)%nprocs, 222, &amp;j, 1, MPI_INT, (myid+1)%nprocs, 333, MPI_COMM_WORLD, &amp;status);<BR>&nbsp;&nbsp;cout &lt;&lt; "MAIN:" &lt;&lt; myid &lt;&lt; " sends to "&lt;&lt; (myid+1)%nprocs &lt;&lt; " " &lt;&lt; myid &lt;&lt; endl;<BR>&nbsp;&nbsp;fflush(stdout);<BR>&nbsp;}<
BR>&nbsp;pret1 = pthread_create(&amp;pt1, NULL, backRecv, NULL);<BR>&nbsp;if(pret1 != 0)<BR>&nbsp;&nbsp; &nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;cout &lt;&lt; myid &lt;&lt; "backRecv Thread Create Failed." &lt;&lt; endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<BR>&nbsp;&nbsp; &nbsp;}<BR>&nbsp;pret2 = pthread_create(&amp;pt2, NULL, backID, NULL);<BR>&nbsp;if(pret2 != 0)<BR>&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; myid &lt;&lt; "backID Thread Create Failed." &lt;&lt; endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<BR>&nbsp;}<BR>&nbsp;//for(i=0; i&lt;10; ++i)<BR>&nbsp;//{<BR>&nbsp;//&nbsp;c += i;<BR>&nbsp;//&nbsp;MPI_Send(&amp;c, 1, MPI_CHAR, (myid+1)%nprocs, 111, MPI_COMM_WORLD);<BR>&nbsp;//&nbsp;cout &lt;&lt; myid &lt;&lt; " send " &lt;&lt; (char)c &lt;&lt; " to " &lt;&lt; (myid+1)%nprocs &lt;&lt; endl;<BR>&nbsp;//}<BR>&nbsp;pthread_join(pt2, NULL);<BR>&nbsp;cout &lt;&lt; "*******************************THREAD 2 SUCESS!" &lt;&lt; endl;<BR>&n
b
sp;pthread_join(pt1, NULL);<BR>&nbsp;cout &lt;&lt; "*******************************THREAD 1 SUCESS!" &lt;&lt; endl;<BR>&nbsp;MPI_Finalize();<BR>&nbsp;cout &lt;&lt; "*******************************MAIN SUCESS!" &lt;&lt; endl;<BR>}<BR><BR>
This peice of code works fine sometimes.&nbsp;But it can fail too and segmentation will occur. I will read the reference you point out. Thanks.<BR>&nbsp;<BR>
<HR id=stopSpelling>
Date: Tue, 22 Sep 2009 08:43:11 -0700<BR>From: Eugene.Loh_at_[hidden]<BR>To: users_at_[hidden]<BR>Subject: Re: [OMPI users] How to create multi-thread parallel program using thread-safe send and recv?<BR><BR>guosong wrote:
<BLOCKQUOTE cite=midCOL102-W1609734903C2BD74E663ADA8DC0_at_phx.gbl>
<STYLE>
.ExternalClass .ecxhmmessage P
{padding:0px;}
.ExternalClass body.ecxhmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
Hi all,<BR>I would like to write a multi-thread parallel program. I used pthread. Basicly, I want to create two background threads besides&nbsp;&nbsp;the main thread(process). For example, if I use&nbsp;"-np 4",&nbsp;the program should have 4 main processes on four processors and two background threads for each main process. So there&nbsp;should be 8 threads totally.</BLOCKQUOTE>Wouldn't there be 4 main threads and 8 "slave" threads for a total of 12 threads?&nbsp; Anyhow, doesn't matter.<BR><BR>I'm not sure where you're starting, but you should at least have a basic understanding of the different sorts of multithreaded programming models in MPI.&nbsp; One is that each process is single threaded.&nbsp; Another is the processes are multithreaded, but only the main thread makes MPI calls.&nbsp; Another is multithreaded, but only one MPI call at a time.&nbsp; Finally, there can be full multithreading.&nbsp; You have to decide which of these programming models you want and which is supported by your MPI (or, if
OMPI, how OMPI was built).<BR><BR>For more information, try the MPI_Init_thread() man page or<BR><A class=ecxmoz-txt-link-freetext href="http://www.mpi-forum.org./docs/mpi21-report.pdf">http://www.mpi-forum.org./docs/mpi21-report.pdf> ... see Section 12.4 on "MPI and Threads".<BR>
<BLOCKQUOTE cite=midCOL102-W1609734903C2BD74E663ADA8DC0_at_phx.gbl>I wrote a test program and it worked unpredictable. Sometimes I got the result I want, but sometimes&nbsp;the program got segmentation fault. I used MPI_Isend and MPI_Irecv for sending and recving. I do&nbsp;not know why? I attached the error message as follow:<BR>&nbsp;<BR>[cheetah:29780] *** Process received signal ***<BR>[cheetah:29780] Signal: Segmentation fault (11)<BR>[cheetah:29780] Signal code: Address not mapped (1)<BR>[cheetah:29780] Failing at address: 0x10<BR>[cheetah:29779] *** Process received signal ***<BR>[cheetah:29779] Signal: Segmentation fault (11)<BR>[cheetah:29779] Signal code: Address not mapped (1)<BR>[cheetah:29779] Failing at address: 0x10<BR>[cheetah:29780] [ 0] /lib64/libpthread.so.0 [0x334b00de70]<BR>[cheetah:29780] [ 1] /act/openmpi/gnu/lib/openmpi/mca_btl_sm.so [0x2b90e1227940]<BR>[cheetah:29780] [ 2] /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so [0x2b90e05d61ca]<BR>[cheetah:29780] [ 3] /act/openmpi/gnu/lib/openmpi/m
ca_pml_ob1.so [0x2b90e05cac86]<BR>[cheetah:29780] [ 4] /act/openmpi/gnu/lib/libmpi.so.0(PMPI_Send+0x13d) [0x2b90dde7271d]<BR>[cheetah:29780] [ 5] pt_muti(_Z6backIDPv+0x29b) [0x409929]<BR>[cheetah:29780] [ 6] /lib64/libpthread.so.0 [0x334b0062f7]<BR>[cheetah:29780] [ 7] /lib64/libc.so.6(clone+0x6d) [0x334! a4d1e3d]<BR>[cheetah:29780] *** End of error message ***<BR>[cheetah:29779] [ 0] /lib64/libpthread.so.0 [0x334b00de70]<BR>[cheetah:29779] [ 1] /act/openmpi/gnu/lib/openmpi/mca_btl_sm.so [0x2b39785c0940]<BR>[cheetah:29779] [ 2] /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so [0x2b397796f1ca]<BR>[cheetah:29779] [ 3] /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so [0x2b3977963c86]<BR>[cheetah:29779] [ 4] /act/openmpi/gnu/lib/libmpi.so.0(PMPI_Send+0x13d) [0x2b397520b71d]<BR>[cheetah:29779] [ 5] pt_muti(_Z6backIDPv+0x29b) [0x409929]<BR>[cheetah:29779] [ 6] /lib64/libpthread.so.0 [0x334b0062f7]<BR>[cheetah:29779] [ 7] /lib64/libc.so.6(clone+0x6d) [0x334a4d1e3d]<BR>[cheetah:29779] *** End of error message ***<BR><BR>&nbsp
;
<BR>I used gdb to "bt" the error and I got :<BR>&nbsp;Program terminated with signal 11, Segmentation fault.<BR>#0&nbsp; 0x00002b90e1227940 in mca_btl_sm_alloc ()<BR>&nbsp;&nbsp; from /act/openmpi/gnu/lib/openmpi/mca_btl_sm.so<BR>(gdb) bt<BR>#0&nbsp; 0x00002b90e1227940 in mca_btl_sm_alloc ()<BR>&nbsp;&nbsp; from /act/openmpi/gnu/lib/openmpi/mca_btl_sm.so<BR>#1&nbsp; 0x00002b90e05d61ca in mca_pml_ob1_send_request_start_copy ()<BR>&nbsp;&nbsp; from /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so<BR>#2&nbsp; 0x00002b90e05cac86 in mca_pml_ob1_send ()<BR>&nbsp;&nbsp; from /act/openmpi/gnu/lib/openmpi/mca_pml_ob1.so<BR>#3&nbsp; 0x00002b90dde7271d in PMPI_Send () from /act/openmpi/gnu/lib/libmpi.so.0<BR>#4&nbsp; 0x0000000000409929 in backID (arg=0x0) at pt_muti.cpp:50<BR>#5&nbsp; 0x000000334b0062f7 in start_thread () from /lib64/libpthread.so.0<BR>#6&nbsp; 0x000000334a4d1e3d in clone () from /lib64/libc.so.6<BR>So can anyone give me some suggestions or advice. Thanks very much.</BLOCKQUOTE> <br /><hr />°ÑMSN
×°½øÊÖ»ú£¬¸ü¶àÁÄÌìÀÖȤµÈÄãÍÚ¾ò£¡ <a href='
http://mobile.msn.com.cn/' target='_new'>Á¢¿ÌÏÂÔØ£¡</a></body>
</html>
--_8cf70815-85b5-44f5-8859-ebdc96183bbd_--