Creating New Threads
First, the ID of the thread
PTHREAD_T: Structure (FreeBSD5.2, Mac OS10.3)/unsigned long int (Linux)
/usr/include/bits/pthreadtypes.h
Get Thread id:pthread_self ()
One instance: Get the main thread ID
#include "apue.h"
int main ()
{
pid_t pid;
pthread_t Tid;
PID = Getpid ();
Tid = Pthread_self ();
printf ("pid is%u, Tid is%x\n", PID, TID);
return 0;
}
Think: is the thread ID out of process scope still valid?
Second, create new threads
int pthread_create (pthread_t *restrict TIDP,
Const pthread_attr_t *restrict attr,
void * (*start_routine) (void *),
void *restrict Arg)
First parameter: ID of the new thread, and if successful, the ID of the new thread is padded back to the memory pointed to by the TIDP
Second parameter: Thread attributes (scheduling policy, inheritance, separation ...) )
Third parameter: callback function (function to be executed by new thread)
Fourth parameter: parameter of the callback function
Return value: Returns 0 successfully, failure returns error code
Need to connect library Libpthread at compile time
Instances: Creating threads, printing IDs
Program diagram
/*author:wj
*date:2015-3-18
*
*
*getpid () Get process ID
*pthread_self () Get ID
*
*int pthread_create (pthread_t *thread,
* Const pthread_attr_t *ATTR,
* void * (*start_routine) (void *),
* void *arg);
* First parameter, new thread ID, create successful system backfill
* Second parameter, new thread to property, NULL as default property
* Third parameter, new thread to start function
* Fourth parameter, passed to new thread
*/
#include "apue.h"
void print_id (char *s)
{
pid_t pid;
pthread_t Tid;
PID = Getpid ();
Tid = Pthread_self ();
printf ("%s pid is%u, Tid is 0x%x\n", S, PID, TID);
}
void *thread_fun (void *arg)
{
PRINT_ID (ARG);
return (void *) 0;
}
int main ()
{
pthread_t Ntid;
int err;
Err = Pthread_create (&ntid, NULL, Thread_fun, "new Thread");
if (Err!= 0)
{
printf ("Create new Thread failed\n");
return 0;
}
PRINT_ID ("Main thread:");
Sleep (2);
return 0;
}
life cycle of threads
First, initial threads/main thread
1, when the C program is running, first run the main function. In the thread code, this particular flow of execution is called the initial thread or the main path. You can do anything a normal thread can do in the initial thread.
2, the main thread is the particularity of it, when the main function returned, will cause the process to end, all threads in the process will also end. This is not a good phenomenon, you can call the Pthread_exit function in the main thread, so that the process waits for all threads to terminate at the end.
3. The main thread accepts parameters through ARGC and argv, while ordinary threads have only one parameter void*
4, in most cases, the main thread runs on the default stack, which can grow to a sufficient length. The normal thread stack is restricted, and an error occurs when the overflow occurs
second, the creation of the thread
1, the main thread is created with the creation of the process
2, other threads can be created by calling the function, the main call pthread_create
3. Note that the new thread may have run before the current thread returns from the function Pthread_create, and even the new thread may have run out before the current thread returns from the function Pthread_create.
iii. Examples: The particularity of the main thread
Click (here) to collapse or open
/*author:wj
*date:2015-3-18
*
*
*getpid () Get process ID
*pthread_self () Get County ID
*
*int pthread_create (pthread_t *thread,
* Const pthread_attr_t *ATTR,
* void * (*start_routine) (void *),
* void *arg);
* First parameter, new thread ID, create successful system backfill
* Second parameter, new thread to property, NULL as default property
* Third parameter, new thread to start function
* Fourth parameter, passed to new thread
*
* The parameters received by the main thread are placed in argv[], and the number of parameters is calculated by argc
*/
#include "apue.h"
struct Student {
int age;
Char name[20];
Char id[4];
};
void *thread_fun (void *stu)
{
Sleep (1);
printf ("Student is%d, the name is%s, the ID is%s\n", (struct student *) stu)->age, ((struct student *) stu)->name, ((St Ruct student *) stu)->id);
return (void *) 0;
}
int main (int argc, char *argv[])
{
pthread_t Tid;
int err;
int *rval;
struct student Stu;
Stu.age = 20;
memcpy (Stu.name, "Zhangsan", 20);
memcpy (Stu.id, "007", 5);
Err = Pthread_create (&tid, NULL, Thread_fun, (void *) (&stu));
if (Err!= 0)
{
printf ("Create new Thread failed\n");
return 0;
}
int i;
printf ("Main thread have%d args\n", argc);
for (i=0; i<argc; i++)
{
printf ("Main thread args is%s\n", argv[i]);
}
Pthread_exit (Rval);
}
Four, four basic states of a thread
1, ready: When the line isconcurrently is created in the ready state, or when the thread is unblocked will also be in a ready state. The ready thread waits for an available processor, and when a running thread is preempted, it immediately returns to the ready state
2. Running: When the processor selects a ready thread to execute, it immediately becomes run state
3, blocking: The thread will be blocked in the following cases: an attempt to lock a locked mutex, wait for a certain condition variable, call singwait wait for the signal has not occurred, execution of the I/O signal cannot be completed, due to memory page error
4, Terminate: The thread usually starts the function to return to terminate itself, or call Pthread_exit exit, or cancel the thread
Five, the thread of recycling
1, the separation of the attributes of the thread:
Detaching a running thread does not affect it, just notifies the current system that the resource to which it belongs can be reclaimed when the thread ends. A thread that is not detached will retain its virtual memory when it terminates, including their stack and other system resources, sometimes called "zombie threads." Default is decoupled when creating threads
2. If the thread has a detached property, the thread will be recycled immediately when it terminates, and the recycle will release all the system and process resources that were not released when the thread was terminated, including the memory space, stack, memory space of the saved register, etc.
3. Terminating the detached thread frees all system resources, but you must release the program resources that are owned by the thread. Memory allocated by malloc or mmap can be freed at any time by any thread, and conditional variables, mutexes, semaphores can be destroyed by any thread as long as they are unlocked or there is no thread waiting. But only the owner of the mutex can unlock it, so you need to unlock the mutex before the thread terminates.