Threads and hybrid applications
The pthread
and RThread
APIs do not mix. Symbian platform heaps are managed thread-wise whereas P.I.P.S. heaps are managed process-wise. Mixingpthread
and RThread
may result in panics due to data being lost or orphaned. So, do not mix the two unless you know what you're doing.
User libraries or executables written using P.I.P.S. must not allocate resources in the context of the calling thread as the thread might be using a private heap which is inaccessible to other threads and might have a different lifetime.
To minimise the risks avoid using RThread
APIs in primarily POSIX applications or libraries (those entering via main()
), and avoid using pthread
in primarily Symbian platform applications or libraries (those entering via E32Main()
).
现状:RThread管理的heap是线程可见的,而pthread管理的heap是进程可见的。
存在的问题:pthread分配的资源可能在symbian platform heaps不可见。
解决办法:避免混合使用两种线程
=======2====================
Poll using select
The select() function call provides functionality to scan descriptors for a ready event. The select() call requires the system to scan through a bit mask of a file descriptor set against its list of open descriptors to check for ready events, only stopping when it reaches a maximum descriptor value. For a system with a relatively small number of open descriptors this is quite efficient but for a large amount of descriptors can be overly burdensome.
The Symbian P.I.P.S. libraries are not expected to be dealing with a very large number of file descriptors and so select() should be satisfactory for any applications on a phone.
Note: P.I.P.S. does not support the poll() function.
Monitoring two pipes using select()
The following code segment shows the usage of the select() function:
int main(int argc, char **argv)
{
FILE* ChildProcessStream1;
FILE* ChildProcessStream2;
int ChildProcessFD1;
int ChildProcessFD2;
fd_set SelectFDs;
int MaxFD;
struct timeval timeout;
int Ret;
//Create child process 1 using popen().
ChildProcessStream1 = popen("/root/PortDoc/Example7_c/Symbian/Child/ChildProg", "r");
if(ChildProcessStream1 == NULL)
{
printf("\n Failure to create child process 1 with popen()\n");
return EXIT_FAILURE;
}
//Create child process 2 using popen().
ChildProcessStream2 = popen("/root/PortDoc/Example7_c/Symbian/Child/ChildProg", "r");
if(ChildProcessStream2 == NULL)
{
printf("\n Failure to create child process 2 with popen()\n");
return EXIT_FAILURE;
}
//Convert streams to file descriptors
ChildProcessFD1 = fileno(ChildProcessStream1);
ChildProcessFD2 = fileno(ChildProcessStream2);
//Setup the select set
FD_ZERO(&SelectFDs);
FD_SET(ChildProcessFD1, &SelectFDs);
MaxFD = ChildProcessFD1;
FD_SET(ChildProcessFD2, &SelectFDs);
//Calculate the largest Descriptor
if (ChildProcessFD2 > MaxFD)
MaxFD = ChildProcessFD2;
//Setup a time out value in case neither return in a sufficient time
timeout.tv_sec = 3;
timeout.tv_usec = 0;
//Issue select request
Ret = select(MaxFD + 1, &SelectFDs, NULL, NULL, &timeout);
if (Ret == -1)
{
//Error occurred
printf("\nCould not poll, error=%d",errno);
return EXIT_FAILURE;
}
else if (Ret == 0)
{
//Timed out
printf("\nTimed Out");
}
else
{
//Create a receive buffer, and zero contents before receiving.
Char RxBuffer[100];
memset(RxBuffer,0,sizeof(RxBuffer));
if (FD_ISSET(ChildProcessFD1, &SelectFDs))
{
//Wait for data from child process 1. Child sends a string.
Int nbytes = read(ChildProcessFD1,RxBuffer,sizeof(RxBuffer));
printf("\nMessage Received from Child1 First =%s",RxBuffer);
}
else if (FD_ISSET(ChildProcessFD2, &SelectFDs))
{
//Wait for data from child process 2. Child sends a string.
Int nbytes = read(ChildProcessFD2,RxBuffer,sizeof(RxBuffer));
printf("\nMessage Received from Child2 First =%s",RxBuffer);
}
}
//Wait for Child Process to complete
pclose(ChildProcessStream1);
pclose(ChildProcessStream2);
return EXIT_SUCCESS;
}